_disable_threads _disable_threads()
This function first posts a notice to all threads that it is time to halt. It then waits until all threads actually have halted, and then then returns a lock object. All other threads will be blocked from running until that object has been freed/destroyed.
It's mainly useful to do things that require a temporary uid/gid change, since on many OSes the effective user and group apply to all threads.
You should make sure that the returned object is freed even if some kind of error is thrown. That means in practice that it should only have references (direct or indirect) from function local variables. Also, it shouldn't be referenced from cyclic memory structures, since those are only destructed by the periodic gc. (This advice applies to mutex locks in general, for that matter.)
gethrdtime()
This module contains classes and functions for interacting and synchronizing with threads.
For convenience some of the classes here are emulated (and are thus available) when threads are not supported.
   Some of the classes that have such fallbacks are: Condition,
   Fifo, Local, Mutex, MutexKey and Queue.
Thread, Mutex, Condition
constant Thread.MUTEX_SUPPORTS_SHARED_LOCKS
Recognition constant for support of shared locks.
 If this symbol exists and is not 0 then the Mutex class
 supports shared locks (ie has Mutex()->shared_lock() et al).
array(Thread.Thread) all_threads()
This function returns an array with the thread ids of all threads.
Thread()
int(0..) get_thread_quanta()
Returns the current thread quanta in nanoseconds.
set_thread_quanta(), gethrtime()
int(0..) set_thread_quanta(int(0..) ns)
Set the thread quanta.
nsNew thread quanta in nanoseconds. A value of zero (default) disables the thread quanta checks.
 When enabled MasterObject.thread_quanta_exceeded() will
 be called when a thread has spent more time than the quanta
 without allowing another thread to run.
Setting a non-zero value that is too small to allow for
   MasterObject.thread_quanta_exceeded() to run is NOT a
   good idea.
Returns the previous thread quanta in nanoseconds.
set_thread_quanta(), gethrtime()
Thread.Thread this_thread()
This function returns the object that identifies this thread.
Thread()
void thread_set_concurrency(int concurrency)
Document this function
Implementation of condition variables.
Condition variables are used by threaded programs to wait for events happening in other threads.
In order to prevent races (which is the whole point of condition variables), the modification of a shared resource and the signal notifying modification of the resource must be performed inside the same mutex lock, and the examining of the resource and waiting for a signal that the resource has changed based on that examination must also happen inside the same mutex lock.
Typical wait operation:
Take mutex lock
Read/write shared resource
Wait for the signal with the mutex lock in released state
Reacquire mutex lock
If needed, jump back to step 2 again
Release mutex lock
Typical signal operation:
Take mutex lock
Read/write shared resource
Send signal
Release mutex lock
You have some resource that multiple treads want to use. To protect this resource for simultaneous access, you create a shared mutex. Before you read or write the resource, you take the mutex so that you get a consistent and private view of / control over it. When you decide that the resource is not in the state you want it, and that you need to wait for some other thread to modify the state for you before you can continue, you wait on the conditional variable, which will temporarily relinquish the mutex during the wait. This way a different thread can take the mutex, update the state of the resource, and then signal the condition (which does not in itself release the mutex, but the signalled thread will be next in line once the mutex is released).
Condition variables are only available on systems with thread support. The Condition class is not simulated otherwise, since that can't be done accurately without continuations.
Signals may currently be sent without holding the lock, but this should be avoided as it may cause the signal to be lost (especially when the signal is not associated with a corresponding change of the shared resource).
Mutex
void broadcast()
broadcast() wakes up all threads currently waiting for this condition.
signal()
Thread.Condition Thread.Condition(Thread.Mutex|void mutex)
mutexOptional Mutex that protects the resource that the
   condition signals for.
void signal()
signal() wakes up one of the threads currently waiting for the
 condition.
Sometimes more than one thread is woken up.
broadcast()
void wait(Thread.MutexKey mutex_key)
void wait(Thread.MutexKey mutex_key, int(0..)|float seconds)
void wait(Thread.MutexKey mutex_key, int(0..) seconds, int(0..999999999) nanos)
Wait for condition.
This function makes the current thread sleep until the condition variable is signalled or the timeout is reached.
mutex_keyA Thread.MutexKey object for a Thread.Mutex. It will be
   unlocked atomically before waiting for the signal and then
   relocked atomically when the signal is received or the timeout
   is reached. Note that it MUST be an exclusive lock.
secondsSeconds to wait before the timeout is reached.
nanosNano (1/1000000000) seconds to wait before the timeout is reached.
   This value is added to the number of seconds specified by seconds.
A timeout of zero seconds disables the timeout.
 The thread that sends the signal should have the mutex locked
 while sending it. Otherwise it's impossible to avoid races where
 signals are sent while the listener(s) haven't arrived to the
 wait calls yet.
The support for timeouts was added in Pike 7.8.121, which was after the first public release of Pike 7.8.
Note that the timeout is approximate (best effort), and may be exceeded if eg the mutex is busy after the timeout.
Note also that any threads waiting on the condition will be woken up when it gets destructed.
Mutex->lock()
A thread farm.
8.0::Thread.Farm
string debug_status()
Get some statistics for the thread farm.
Concurrent.Future run(function(:void) f, mixed ...  args)
Register a job for the thread farm.
fFunction to call with @args to
   perform the job.
argsThe parameters for f.
Returns a Result object for the job.
In Pike 7.8 and earlier this function
   was broken and returned a Result
   object that wasn't connected to the job.
run_async()
void run_async(function(:void) f, mixed ...  args)
Register a job for the thread farm
 where the return value from f is
 ignored.
fFunction to call with @args to
   perform the job.
argsThe parameters for f.
In some versions of Pike 8.0 and earlier, errors thrown
   by f were silently suppressed.
run()
Concurrent.Future(< array >) run_multiple(array(array(function(:void)|array)) fun_args)
Register multiple jobs.
fun_argsAn array of arrays where the first element is a function to call, and the second is a corresponding array of arguments.
Returns a Concurrent.Future object with an array
   with one element for the result for each
   of the functions in fun_args.
Do not modify the elements of fun_args
   before the result is available.
If any of the functions in fun_args throws
   and error, all of the accumulated results
   (if any) will be dropped from the result, and
   the first backtrace be provided.
run_multiple_async()
void run_multiple_async(array fun_args)
Register multiple jobs where the return values are to be ignored.
fun_argsAn array of arrays where the first element is a function to call, and the second is a corresponding array of arguments.
Do not modify the elements of fun_args
   before the result is available.
run_multiple()
int set_max_num_threads(int(1..) to)
Set the maximum number of worker threads that the thread farm may have.
toThe new maximum number.
 If there are more worker threads than to,
 the function will wait until enough threads
 have finished, so that the total is to or less.
 The default maximum number of worker threads is 20.
void set_thread_name_cb(function(object, string:void) cb, void|string prefix)
Provide a callback function to track names of threads created by the farm.
cbThe callback function. This will get invoked with the thread as the
   first parameter and the name as the second whenever a thread is
   created. When the same thread terminates the callback is invoked
   again with 0 as the second parameter. Set cb to 0 to stop
   any previously registered callbacks from being called.
prefixAn optional name prefix to distinguish different farms. If not given a prefix will be generated automatically.
A worker thread.
string debug_status()
Get some statistics about the worker thread.
object Thread.Farm.ValueAdjuster.r
object Thread.Farm.ValueAdjuster.r2
int Thread.Farm.ValueAdjuster.i
mapping Thread.Farm.ValueAdjuster.v
protected  local  void __create__(object r, object r2, int i, mapping v)
Thread.Farm.ValueAdjuster Thread.Farm.ValueAdjuster(object r, object r2, int i, mapping v)
Fifo implements a fixed length first-in, first-out queue.
 A fifo is a queue of values and is often used as a stream of data
 between two threads.
Queue
inherit Mutex : lock
inherit Condition : r_cond
inherit Condition : w_cond
Thread.Fifo Thread.Fifo()
Thread.Fifo Thread.Fifo(int size)
Create a fifo. If the optional size argument is present it
 sets how many values can be written to the fifo without blocking.
 The default size is 128.
mixed peek()
This function returns the next value in the fifo if there are
 any there. If there are no values present in the fifo then
 UNDEFINED will be returned.
read(), try_read()
mixed read()
This function retrieves a value from the fifo. Values will be returned in the order they were written. If there are no values present in the fifo the current thread will sleep until some other thread writes one.
peek(), try_read(), read_array(), write()
array read_array()
This function returns all values in the fifo as an array. The values in the array will be in the order they were written. If there are no values present in the fifo the current thread will sleep until some other thread writes one.
read(), try_read_array()
int size()
This function returns the number of elements currently in the fifo.
read(), write()
mixed try_read()
This function retrieves a value from the fifo if there are any
 there. Values will be returned in the order they were written.
 If there are no values present in the fifo then UNDEFINED
 will be returned.
peek(), read()
array try_read_array()
This function returns all values in the fifo as an array but doesn't wait if there are no values there. The values in the array will be in the order they were written.
read_array()
int try_write(mixed value)
Append a value to the end of the fifo. If there is no more
 room in the fifo then zero will be returned, otherwise the
 number of items in the fifo after the write is returned.
read()
int write(mixed value)
Append a value to the end of the fifo. If there is no more
 room in the fifo the current thread will sleep until space is
 available. The number of items in the queue after the write is
 returned.
read()
Thread local variable storage.
 This class allows you to have variables which are separate for each
 thread that uses it. It has two methods: get() and set(). A value
 stored in an instance of Local can only be retrieved by that
 same thread.
This class is simulated when Pike is compiled without thread support, so it's always available.
__generic__ mixed ValueType = mixed
Type for the value to be stored in the thread local storage.
ValueType get()
Get the thread local value.
Returns the value prevoiusly stored in the Local object by
   the set() method by this thread (if set). Returns UNDEFINED
   if no value has been set by the current thread.
set()
ValueType set(ValueType value)
Set the thread local value.
 This sets the value returned by the get method.
 Calling this method does not affect the value returned by get() when
 it's called by another thread (ie multiple values can be stored at the
 same time, but only one value per thread).
This function returns its argument.
Note that the value set can only be retreived by the same thread.
get()
Mutex is a class that implements mutual exclusion and shared locks.
Mutex locks are used to prevent multiple threads from simultaneously executing sections of code which access or change shared data. The basic operations for a mutex is locking and unlocking. If a thread attempts to lock an already locked mutex the thread will sleep until the mutex is unlocked.
This class is simulated when Pike is compiled without thread support, so it's always available.
Support for shared locks was added in Pike 8.1.14.
In POSIX threads, mutex locks can only be unlocked by the same thread that locked them. In Pike any thread can unlock a locked mutex.
string sprintf(string format, ... Thread.Mutex arg ... )
Describes the mutex including the thread that currently holds the lock (if any).
Condition cond()
Create a Condition.
This function is equivalent to
Thread.Condition(mux);
Condition
Thread.MutexKey current_locking_key()
This mutex method returns the key object currently governing the lock on this mutex. 0 is returned if the mutex isn't locked.
Thread()
Thread.Thread current_locking_thread()
This mutex method returns the object that identifies the thread that has locked the mutex. 0 is returned if the mutex isn't locked.
Thread()
Concurrent.Future(< Thread.MutexKey >) future_lock()
This function is similar to lock(), but will return
 a Concurrent.Future(<Thread.MutexKey>) that will
 complete successfully when the Mutex is locked.
Avoid having multiple future_lock's for different Mutexes
   pending concurrently in the same conceptual thread as this will
   likely cause dead-locks.
Concurrent.Future(< Thread.MutexKey >) future_shared_lock()
This function is similar to shared_lock(), but will return
 a Concurrent.Future(<Thread.MutexKey>) that will
 complete successfully when the Mutex is locked.
Avoid having multiple future_shared_lock's for different Mutexes
   pending concurrently in the same conceptual thread as this will
   likely cause dead-locks.
MutexKey lock()
MutexKey lock(int type)
MutexKey lock(int type, int(0..)|float seconds)
MutexKey lock(int type, int(0..) seconds, int(0..999999999) nanos)
This function attempts to lock the mutex. If the mutex is already locked by a different thread the current thread will sleep until the mutex is unlocked. The value returned is the 'key' to the lock. When the key is destructed or has no more references the mutex will automatically be unlocked.
 The type argument specifies what lock() should do if the
 mutex is already locked by this thread:
 | Throw an error.  | 
 | Sleep until the mutex is unlocked. Useful if some other thread will unlock it.  | 
 | Return zero. This allows recursion within a locked region of code, but in conjunction with other locks it easily leads to unspecified locking order and therefore a risk for deadlocks.  | 
secondsSeconds to wait before the timeout is reached.
nanosNano (1/1000000000) seconds to wait before the timeout is reached.
   This value is added to the number of seconds specified by seconds.
A timeout of zero seconds disables the timeout.
Returns a MutexKey on success and 0 (zero) on timeout.
The support for timeouts was added in Pike 8.1.14, which was before the first public release of Pike 8.1.
Note that the timeout is approximate (best effort), and may be exceeded if eg the interpreter is busy after the timeout.
If the mutex is destructed while it's locked or while threads are
 waiting on it, it will continue to exist internally until the last
 thread has stopped waiting and the last MutexKey has
 disappeared, but further calls to the functions in this class will
 fail as is usual for destructed objects.
Pike 7.4 and earlier destructed any outstanding lock when the
 mutex was destructed, but threads waiting in lock still got
 functioning locks as discussed above. This is inconsistent no
 matter how you look at it, so it was changed in 7.6. The old
 behavior is retained in compatibility mode for applications that
 explicitly destruct mutexes to unlock them.
trylock()
MutexKey shared_lock()
MutexKey shared_lock(int type)
MutexKey shared_lock(int type, int(0..)|float seconds)
MutexKey shared_lock(int type, int(0..) seconds, int(0..999999999) nanos)
This function attempts to lock the mutex. If the mutex is already locked by a different thread the current thread will sleep until the mutex is unlocked. The value returned is the 'key' to the lock. When the key is destructed or has no more references the mutex will automatically be unlocked.
 The type argument specifies what lock() should do if the
 mutex is already locked exclusively by this thread:
 | Throw an error.  | 
 | Sleep until the mutex is unlocked. Useful if some other thread will unlock it.  | 
 | Return zero. This allows recursion within a locked region of code, but in conjunction with other locks it easily leads to unspecified locking order and therefore a risk for deadlocks.  | 
secondsSeconds to wait before the timeout is reached.
nanosNano (1/1000000000) seconds to wait before the timeout is reached.
   This value is added to the number of seconds specified by seconds.
A timeout of zero seconds disables the timeout.
Returns a MutexKey on success and 0 (zero) on timeout.
Note that the timeout is approximate (best effort), and may be exceeded if eg the interpreter is busy after the timeout.
Note that if the current thread already holds a shared key,
   a new will be created without waiting, and regardless of
   the value of type.
If the mutex is destructed while it's locked or while threads are
 waiting on it, it will continue to exist internally until the last
 thread has stopped waiting and the last MutexKey has
 disappeared, but further calls to the functions in this class will
 fail as is usual for destructed objects.
Support for shared keys was added in Pike 8.1.
lock(), trylock(), try_shared_lock()
MutexKey try_shared_lock()
MutexKey try_shared_lock(int type)
This function performs the same operation as shared_lock(),
 but if the mutex is already locked exclusively, it will return
 zero instead of sleeping until it's unlocked.
Support for shared keys was added in Pike 8.1.
shared_lock(), lock(), trylock()
MutexKey trylock()
MutexKey trylock(int type)
This function performs the same operation as lock(), but if the mutex
 is already locked, it will return zero instead of sleeping until it's
 unlocked.
lock()
Objects of this class are returned by Mutex()->lock()
 and Mutex()->trylock() et al. They are also passed as arguments
 to Condition()->wait().
As long as they are held, the corresponding mutex will be locked.
The corresponding mutex will be unlocked when the object is destructed (eg by not having any references left).
Mutex, Condition
string sprintf(string format, ... Thread.MutexKey arg ... )
void downgrade()
Downgrade an exclusive lock into a shared lock.
 A downgraded lock may be upgraded back to an exclusive lock
 by calling upgrade() or try_upgrade().
upgrade(), try_upgrade()
bool try_upgrade()
Try to upgrade a downgraded lock into an exclusive lock.
 | Returns   | 
 | Returns   | 
downgrade(), upgrade()
bool upgrade()
bool upgrade(int(0..)|float seconds)
bool upgrade(int(0..) seconds, int(0..999999999) nanos)
Upgrade a downgraded lock into an exclusive lock.
secondsSeconds to wait before the timeout is reached.
nanosNano (1/1000000000) seconds to wait before the timeout is reached.
   This value is added to the number of seconds specified by seconds.
A timeout of zero seconds disables the timeout.
Note that the timeout is approximate (best effort), and may be exceeded if eg the interpreter is busy after the timeout.
Waits until all concurrent shared locks are released, and upgrades this lock into being an exclusive lock. Any attempts to make new shared locks will block as soon as this function is called.
downgrade(), try_upgrade()
Queue implements a queue, or a pipeline. The main difference
 between Queue and Fifo is that Queue
 will never block in write(), only allocate more memory.
Ought to be made API-compatible with ADT.Queue.
Fifo, ADT.Queue
inherit Mutex : lock
inherit Condition : r_cond
mixed peek()
This function returns the next value in the queue if there are
 any there. If there are no values present in the queue then
 UNDEFINED will be returned.
peek(), read(), try_read(), write()
array peek_array()
Returns a snapshot of all the values in the queue, in the order they were written. The values are still left in the queue, so if other threads are reading from it, the returned value should be considered stale already on return.
mixed read()
This function retrieves a value from the queue. Values will be returned in the order they were written. If there are no values present in the queue the current thread will sleep until some other thread writes one.
peek(), try_read(), write()
array read_array()
This function returns all values in the queue as an array. The values in the array will be in the order they were written. If there are no values present in the queue the current thread will sleep until some other thread writes one.
read(), try_read_array()
int size()
This function returns the number of elements currently in the queue.
read(), write()
mixed try_read()
This function retrieves a value from the queue if there are any
 there. Values will be returned in the order they were written.
 If there are no values present in the queue then UNDEFINED
 will be returned.
peek(), read(), write()
array try_read_array()
This function returns all values in the queue as an array but doesn't wait if there are no values there. The values in the array will be in the order they were written.
read_array()
int write(mixed value)
This function puts a value last in the queue. If the queue is
 too small to hold the value it will be expanded to make room.
 The number of items in the queue after the write is returned.
read()
Implements an inverted-semaphore-like resource
 counter.  A thread can poll or perform a blocking wait for the
 resource-count to drop below a certain level.
ResourceCountKey, Condition, Mutex
final  ResourceCountKey acquire()
Increments the resource-counter.
A ResourceCountKey to decrement the resource-counter again.
final  bool drained(void|int level)
levelThe maximum level that is considered drained.
True if the resource counter drops to equal or below level.
final  void wait_till_drained(void|int level)
Blocks until the resource-counter dips to max level.
levelThe maximum level that is considered drained.
When this key is destroyed, the corresponding resource counter will be decremented.
ResourceCount, MutexKey
private  inherit __builtin.DestructImmediate : DestructImmediate
string sprintf(string format, ... Thread.Thread arg ... )
Returns a string identifying the thread.
array(mixed) backtrace(int|void flags)
Returns the current call stack for the thread.
flagsA bit mask of flags affecting generation of the backtrace.
Currently a single flag is defined:
 | Return  Note that since these values are "live", they may change or dissapear at any time unless the corresponding thread has been halted or similar.  | 
The result has the same format as for predef::backtrace().
predef::backtrace()
Thread.Thread Thread.Thread(function(mixed ... :mixed|void) f, mixed ...  args)
This function creates a new thread which will run simultaneously
 to the rest of the program. The new thread will call the function
 f with the arguments args. When f returns the thread will cease
 to exist.
All Pike functions are 'thread safe' meaning that running a function at the same time from different threads will not corrupt any internal data in the Pike process.
The returned value will be the same as the return value of
   this_thread() for the new thread.
This function is only available on systems with POSIX or UNIX or WIN32 threads support.
Mutex, Condition, this_thread()
int gethrvtime(void|int nsec)
The CPU time consumed by this thread.
predef::gethrvtime()
protected  int id_number()
Returns an id number identifying the thread.
void interrupt()
void interrupt(string msg)
Interrupt the thread with the message msg.
 This function causes the thread to throw an error
 where the message defaults to "Interrupted.\n".
The argument msg is currently ignored.
Interrupts are asynchronous, and are currently not queued.
Due to the asynchronous nature of interrupts, it may take some time before the thread reacts to the interrupt.
void kill(int|void exit_value)
Interrupt the thread, and terminate it as if it had
 terminated with the value exit_value.
Interrupts are asynchronous, and are currently not queued.
Due to the asynchronous nature of interrupts, it may take some time before the thread reacts to the interrupt.
Killing the backend thread (aka the main thread) is
   equivalent to calling predef::kill().
int status()
Returns the status of the thread.
 | The thread has not yet started executing.  | 
 | The thread has started and has not yet terminated.  | 
 | The thread has terminated by returning a value from the thread function.  | 
 | The thread has terminated by throwing an uncaught error.  | 
mixed wait()
Waits for the thread to complete, and then returns the value returned from the thread function.
Rethrows the error thrown by the thread if it exited by throwing an error.