Re: Stdio.Buffer.set_buffer_mode revisited
"Per Hedbor () @ Pike (-) importm?te f?r mailinglistan" <[email protected]>
| Newsgroups | gmane.comp.lang.pike.user |
|---|---|
| Message-ID | <[email protected]> |
> Personally I would have written the code to be nonblocking at that
> level, and do the blocking stuff at a level where it is easier
> (in the query method, as an example).
A class like this might be useful to have somewhere, incidentally:
| protected Thread.Thread backend_thread;
| /* initialized in various ways in our code. */
|
| class Blocking( function(function(mixed:void),mixed...:void) async_func )
| {
| mixed `()(mixed ... args )
| {
| Thread.Condition c = Thread.Condition();
| Thread.Mutex mt = Thread.Mutex();
| bool finished;
| mixed rep;
|
| void got_reply( mixed _rep )
| {
| rep = _rep;
| finished=true;
| Thread.MutexKey lock = mt->lock();
| c->signal();
| lock = 0;
| };
| void run()
| {
| async_func( @args, got_reply );
| if( backend_thread == this_thread() )
| {
| while(!finished)
| backend(3600.0);
| }
| else
| {
| Thread.MutexKey lock = mt->lock();
| while( !finished )
| c->wait( lock );
| }
| return rep;
| };
| return run();
| }
| }
We keep funcitonality like this in a 'ThreadUtils' module the mini
server, but that is not really an all that logical place, really.
Anyway, it makes it fairly trivial to convert a callback based API to
a blocking one:
| void async_query( function when_done, string query, mapping bindings );
| void async_big_query( function when_done, mixed ... );
|
| Blocking query = Blocking(async_query);
| Blocking big_query = Blocking(async_query);
The main advantage of this is that there is no longer any need for a
single thread in the low-level code, and in fact, it works even if the
client code does not use threads either. Everything is non-blocking,
the blocking API either waits for the result or runs the backend, as
needed.
Personally I tend to see use of threads as a failure. :)
--
Per Hedbor