2001-01-31
2001-01-31 01:06:09 by Per Hedbor <ph@opera.com>
-
50b58b16933da216fb720471e6c56c8745c362e6
(166 lines)
(+80/-86)
[
Show
| Annotate
]
Branch: 5.2
Fixed [Bug 1056 (#1056)]
Rev: server/base_server/roxen.pike:1.619
4:
// Per Hedbor, Henrik Grubbström, Pontus Hagland, David Hedbor and others.
// ABS and suicide systems contributed freely by Francesco Chemolli
- constant cvs_version="$Id: roxen.pike,v 1.618 2001/01/31 01:01:41 per Exp $";
+ constant cvs_version="$Id: roxen.pike,v 1.619 2001/01/31 01:06:09 per Exp $";
// Used when running threaded to find out which thread is the backend thread,
// for debug purposes only.
409:
* handle() stuff
*/
- #ifndef THREADS
- // handle function used when THREADS is not enabled.
- local static void unthreaded_handle(function f, mixed ... args)
- {
- f(@args);
- }
-
- function handle = unthreaded_handle;
- #else
- function handle = threaded_handle;
- #endif
-
- /*
- * THREADS code starts here
- */
+
#ifdef THREADS
-
+ // function handle = threaded_handle;
Thread do_thread_create(string id, function f, mixed ... args)
{
477: Inside #if defined(THREADS)
{
return lambda( mixed ... args ) { thread_create( f, @args ); };
}
- #else
- function async_sig_start( function f, int really )
- {
- class SignalAsyncVerifier( function f )
- {
- static int async_called;
-
- void really_call( array args )
- {
- async_called = 0;
- f( @args );
- }
-
- void call( mixed ... args )
- {
- if( async_called )
- {
- report_debug("\n\n"
- "Async calling failed for %O, calling synchronous\n", f);
- report_debug("Backtrace at time of hangup:\n%s\n",
- describe_backtrace( backtrace() ));
- f( @args );
- return;
- }
- async_called=1;
- call_out( really_call, 0, args );
- }
- };
- // call_out is not really useful here, since we probably want to run
- // the signal handler immediately, not whenever the backend thread
- // is available. /per
- //
- // Calling directly like this may however lead to recursive mutex
- // lock errors. The problem cannot be solved using lock(2) since the
- // internal structures may be in an inconsistent state from the
- // previous call, and waiting for the lock probably leads to a
- // deadlock. /noring
- //
- // But on the other hand, you are not very likely to have any mutex
- // locks in an unthreaded pike, since it's quite impossible. /per
- //
- // But still, the problems with inconsistent internal states are
- // there. The API:s for many (thread safe) objects are designed to
- // only allow one (1) caller at any given time. It's a bug if this
- // restriction can be circumvented using signals. I suggest that
- // Thread.Mutex takes care of this problem in non-threaded mode.
- // / noring
- //
- // Apparantly it already did that. :-)
- //
- // I also fixed SIGHUP to be somewhat more asynchronous.
- //
- // I also added a rather small amount of magic so that it is called
- // asynchronously the first time it is received, but repeated
- // signals are not called asynchronously unless the first signal
- // handler was actually called.
- //
- // Except for the SIGQUIT signal, which dumps a backtrace. It would
- // be an excercise in futility to call that one asynchronously.
- //
- // I hope that this will solve all your problems. /per
- if( really > 0 )
- return lambda( mixed ... args ){ call_out( f, 0, @args ); };
- if( really < 0 )
- return f;
- return SignalAsyncVerifier( f )->call;
- }
- #endif
-
+
local static Queue handle_queue = Queue();
//! Queue of things to handle.
//! An entry consists of an array(function fp, array args)
602:
}
}
- local static void threaded_handle(function f, mixed ... args)
+ local static void handle(function f, mixed ... args)
{
handle_queue->write(({f, args }));
}
652:
}
}
}
+
+ #else
+ // handle function used when THREADS is not enabled.
+ local static void handle(function f, mixed ... args)
+ {
+ f(@args);
+ }
+
+ // function handle = unthreaded_handle;
+
+ function async_sig_start( function f, int really )
+ {
+ class SignalAsyncVerifier( function f )
+ {
+ static int async_called;
+
+ void really_call( array args )
+ {
+ async_called = 0;
+ f( @args );
+ }
+
+ void call( mixed ... args )
+ {
+ if( async_called )
+ {
+ report_debug("\n\n"
+ "Async calling failed for %O, calling synchronous\n", f);
+ report_debug("Backtrace at time of hangup:\n%s\n",
+ describe_backtrace( backtrace() ));
+ f( @args );
+ return;
+ }
+ async_called=1;
+ call_out( really_call, 0, args );
+ }
+ };
+ // call_out is not really useful here, since we probably want to run
+ // the signal handler immediately, not whenever the backend thread
+ // is available. /per
+ //
+ // Calling directly like this may however lead to recursive mutex
+ // lock errors. The problem cannot be solved using lock(2) since the
+ // internal structures may be in an inconsistent state from the
+ // previous call, and waiting for the lock probably leads to a
+ // deadlock. /noring
+ //
+ // But on the other hand, you are not very likely to have any mutex
+ // locks in an unthreaded pike, since it's quite impossible. /per
+ //
+ // But still, the problems with inconsistent internal states are
+ // there. The API:s for many (thread safe) objects are designed to
+ // only allow one (1) caller at any given time. It's a bug if this
+ // restriction can be circumvented using signals. I suggest that
+ // Thread.Mutex takes care of this problem in non-threaded mode.
+ // / noring
+ //
+ // Apparantly it already did that. :-)
+ //
+ // I also fixed SIGHUP to be somewhat more asynchronous.
+ //
+ // I also added a rather small amount of magic so that it is called
+ // asynchronously the first time it is received, but repeated
+ // signals are not called asynchronously unless the first signal
+ // handler was actually called.
+ //
+ // Except for the SIGQUIT signal, which dumps a backtrace. It would
+ // be an excercise in futility to call that one asynchronously.
+ //
+ // I hope that this will solve all your problems. /per
+ if( really > 0 )
+ return lambda( mixed ... args ){ call_out( f, 0, @args ); };
+ if( really < 0 )
+ return f;
+ return SignalAsyncVerifier( f )->call;
+ }
#endif /* THREADS */