[ANN] Helper Threads Toolkit

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

[ANN] Helper Threads Toolkit

Javier Guerra Giraldez

It's there:

http://luaforge.net/projects/helper-threads/


--
Javier

attachment0 (207 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

RE: [ANN] Helper Threads Toolkit

Vijay Aswadhati-2
On Friday, March 10, 2006 4:47 PM, Javier Guerra wrote:


> It's there:
>
> http://luaforge.net/projects/helper-threads/

Looks squeaky clean. Have not played with it yet though.

There are some use cases that I don't understand how I could handle
using this package.

I have C++ tasks (that I wish I could make them invocable from Lua)
that can be canceled or it's state updated from one or more tasks.

For example I have a task to stream a live audio file (that is being
recorded by another task). The streaming task basically sits in a
loop reading the audio file and sending it out to the network; when
it hits EOF condition it checks a member variable that indicates if
the audio file is live (i.e still being recorded) or not. If live it
will yield a little while and then continue reading the file.

Meanwhile the recording task sends a message ('application event')
when it is done recording  to the streaming task which in turn sets
the member variable (_is_live) to false which in turn will make the
streaming task to quit the loop on the next EOF condition.

There is also another use case where yet another task may just ask
the streaming task to quit.

In the scheme that you have designed, 'cancel' and
'update_live_state' would be methods of the streaming task. Am I on
the right track?

Cheers
Vijay Aswadhati



Reply | Threaded
Open this post in threaded view
|

Re: [ANN] Helper Threads Toolkit

Javier Guerra Giraldez
On Friday 10 March 2006 9:20 pm, Vijay Aswadhati wrote:
> Looks squeaky clean. Have not played with it yet though.

really? i still have to write some docs...

> There are some use cases that I don't understand how I could handle
> using this package.
>
> I have C++ tasks (that I wish I could make them invocable from Lua)
> that can be canceled or it's state updated from one or more tasks.

i think of two approaches:

1) extend the toolkit: add a Cancel(task) function, and rename Finish(task) to
State(task, ...). also add a send-as-event(task) callable from the work() C
function, that would put the task in the out queue before the end of work().  
that way, the Lua code would be 'notified' by the appearance of the task in
the output queue, and the State(task, ...) would get any data it needs,
without stopping or finishing the task.  one-shot tasks would be deleted
after State(task) if the task was in the TSK_DONE state.

2) separate the background work from its Lua interface:  spawn your work
threads with your own API, not using Helper Threads; but add helperfuncs to
get any event.  those tasks are 'done' when there's a corresponding event by
the work thread.

something like this:
-------
in = helper.newqueue()
out=helper.newqueue()
-- several threads, so the events won't block
evt_th1 = helper.newthread(in,out)
evt_th2 = helper.newthread(in,out)
evt_th3 = helper.newthread(in,out)
evt_th4 = helper.newthread(in,out)

recorder = newrecorder(params...)
streamer = newstreamer(params...)

recdone_tsk = isdone (recorder)
in:addtask (recdone_tsk)
strmdone_tsk = isdone (recorder)
in:addtask (strmdone_tsk)

isfill_tsk = get_recorded_data (recorder)
in:addtask (isfill_tsk)
isempty_tsk  = nil

while true do
  local data = ""

  evt = out:wait()

  if evt == isfill_tsk then
    data = helper.finish(evt)
    isfill_tsk = getrecordeddata (recorder)
    in:addtask (isfill_tsk)

  elseif evt == isempty_tsk then
    helper.finish(evt)
    local isempty_tsk = streamsomedata (streamer, data)
    in:addtask (isempty_tsk)

  elseif evt == recdone_tsk then
    rec_endstatus = helper.finish(evt)
    recorder = nil
    if streamer == nil then
      break
    else
      kill (streamer)
    end

  elseif evt == strmdone_tsk  then
    strm_endstatus = helper.finish(evt)
    streamer = nil
    if recorder == nil then
      break
    else
      kill(recorder)
    end
  end

end

--------------------

getrecordeddata(recorder) would finish when there's some data, but the
recorder wouldn't finish.

streamsomedata would finish when the streamer can accept more data, but before
it starves (in fact, it could just append a list, so it doesn't need to be a
helper func....).

isdone() would finish when the given work is done (either because there's no
more input, or because it was cancelled), and it's finish method returns any
end status.

newrecorder(), newstreamer() and kill() are usual C functions that create and
kill your working threads.

i think (2) is more general, but needs more work from the end developer (you).

for (1) to work, i would add a cancel() method to the ops structure, but i'm
not sure (yet) if there's a race condition if a running task signals an event
(appearing in the out queue while still in the TSK_BUSY state), and finishes
before (or while) the Lua code calls state(task)

for (2) to make sense, it's needed to differentiate "worker threads" from
"helper threads". a thread that stays up working for prolonged time, getting
and generating data is a 'worker thread', and out of my toolkit scope.  
'helper threads', OTOH, are a trick used to show a non-blocking API to
blocking processes.

in this case, it's possible to use helper threads as a mechanism to
communicate with worker threads.  the advantage is that it's (relatively)
easy to use blocking semaphores and cond variables to get the events and then
notify asynchronously to the Lua code.

until now, i had thought that worker threads were too much case-specific to
bother supporting them, but looking at your description, i think it wouldn't
(shouldn't?) be hard to do.

thanks for the feedback!

--
Javier

attachment0 (207 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: [ANN] Helper Threads Toolkit

Javier Guerra Giraldez
In reply to this post by Vijay Aswadhati-2
On Friday 10 March 2006 9:20 pm, Vijay Aswadhati wrote:
> I have C++ tasks (that I wish I could make them invocable from Lua)
> that can be canceled or it's state updated from one or more tasks.

i have renamed the helper.finish(task) function to helper.update(task) and
added the C function signal_task(). the idea is that it's now useful as a
general communication between Lua code and a working thread.

from the worker thread, when you want to send something to Lua, you call
signal_task(), passing a boolean true if you want the thread to be paused.  
this causes the task to appear in the output queue.  the Lua code then should
call update(task, ...) to get any intermediate data, or even to send some
data to the thread.  thread will be automatically unpaused, if appropriate.

please check it in CVS.

--
Javier

attachment0 (207 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

RE: [ANN] Helper Threads Toolkit

Vijay Aswadhati-2
On Sunday, March 12, 2006 9:53 PM, Javier Guerra wrote:

> i have renamed the helper.finish(task) function to
> helper.update(task) and added the C function signal_task(). The
> idea is that it's now useful as a general communication between
> Lua code and a working thread.
>
> from the worker thread, when you want to send something to Lua,
> you call signal_task(), passing a boolean true if you want the
> thread to be paused.
>
> this causes the task to appear in the output queue.  the Lua code
> then should call update(task, ...) to get any intermediate data,
> or even to send some data to the thread.  thread will be
> automatically unpaused, if appropriate.
>
> please check it in CVS.

Thank you. I will take a look.

Cheers
Vijay Aswadhati


Reply | Threaded
Open this post in threaded view
|

Re: [ANN] Helper Threads Toolkit

Javier Guerra Giraldez
In reply to this post by Javier Guerra Giraldez

I've just uploaded the third revision of HTT, it now includes a background
file I/O, a simple coroutine scheduler and documentation for everything.

http://luaforge.net/projects/helper-threads/

it's now complete enough for using, the most important missing part is a
Socket library... after that, maybe SQL, a HTTP client... anything

i think it's possible to merge it with Rings, and get a simple way to do
preemptive multithreading Lua code (similar to LuaTasks, but not to
LuaThreads, unfortunately)

PD: Also missing is a windows port... any takers?

--
Javier

attachment0 (207 bytes) Download Attachment