Re: Non Blocking Support
- Posted by Jonas Temple <jtemple at yhti.net> Feb 15, 2007
- 615 views
CChris wrote: > > <a href="http://www.innovativesys.net">http://www.innovativesys.net</a> > > Did you plainly insert a task_yield() call at line 33376 or is it > anything subtler? > > CChris Actually, looking at what I did, I insert this into two places. And, of course, I can't remember why I did the first! :) The first is in eventLoop() procedure:
-- Gather some entropy for the random integer routine w32Seed = remainder((w32Seed * peek4u(msg+16)) + 1 + peek4u(msg+20) * peek4u(msg+24), #FFFFFFFF) w32Proc( xTranslateMessage, { msg } ) w32Proc( xDispatchMessage, { msg } ) task_yield()
The second is in doEvents():
global procedure doEvents(integer id) atom msg, hWnd if vWinMainState != kStarted then return end if if id = 0 then hWnd = 0 else if validId(id) = w32False then return end if hWnd = getHandle(id) end if -- Allocate a message buffer msg = w32acquire_mem(0, SIZEOF_MSG) if w32Func( xPeekMessage, { msg, hWnd, 0, 0, PM_REMOVE } ) then w32Proc( xTranslateMessage, { msg } ) w32Proc( xDispatchMessage, { msg } ) task_yield() end if w32release_mem(msg) end procedure
And to be honest, I haven't noticed any performance depreciation using task_yield() in these routines. Sorry I can't give you the exact line numbers, my copy of Win32lib has some "tweaks". Just in case you're curious, here's how I modified my code (which was not a lot!) * included tdll.e (of course) * changed my open_dll() call to open_tdll() * For functions that I wanted non-blocking, I replaced the define_c_func() calls with define_t_func() calls. In my case the only change was replacing the "c" in define_c_func with "t". The parameters to the define_t_func were identical to define_c_func. I then replaced the c_func() calls with t_func(). Again, the only change was the "c" to "t". I even left all the rest of the C functions with the standard define_c_func/c_func Euphoria routines and they worked fine! In my main program I coded a routine to kick off the task and then wait until it was complete:
task = task_create(routine_id("execute_task"), {invoked_from, ctl_index}) task_schedule(task,1) -- Process message loop until end of task while find(task, task_list()) do doEvents(0) task_yield() end while
Carefully placed task_yield() calls, both in the main program and in Win32Lib seemed to keep things in order. I did have to rework a HUGE portion of my code to eliminate my over-use of globals. But that was my issue, not tdll. I just had to ensure that one task would not interfere with the values in another task. I was having some problems at first before I figured out how to place calls to task_yield() and Daniel suggested his APC DLL which he said was better than TDLL but I could not figure out how to use the library and never got a response back from him on a request for documentation. I just found the TDLL calls easier to understand. HTH, Jonas Temple http://www.innovativesys.net