Back to index

courier  0.68.2
havepthread.h
Go to the documentation of this file.
00001 #ifndef       havepthread_h
00002 #define       havepthread_h
00003 
00004 /*
00005 ** Copyright 2000 Double Precision, Inc.  See COPYING for
00006 ** distribution information.
00007 */
00008 
00009 
00010 #if    HAVE_CONFIG_H
00011 #include      "config.h"
00012 #endif
00013 
00014 /*
00015 
00016 This library encapsulates Posix threads in such a fashion as to be
00017 able to transparently emulate the encapsulation if Posix threads are
00018 not available.
00019 
00020 That is, the caller simply implements the documented interface, and if Posix
00021 threads are not available, this library will provide stub functions that will
00022 implement a functional equivalent (although probably a far less efficient
00023 one).
00024 
00025 The interface implement by this library is as follows:
00026 
00027 * A function is defined which will be executed by multiple threads in parallel.
00028 
00029 * When this function returns, another 'cleanup' function will be called, except
00030   that this cleanup function will be single-threaded.
00031 
00032   In fact, the cleanup function may be executed by any thread.  All this is
00033   is when the main function, the work function, completes, a mutex is locked
00034   for the duration of the cleanup function call.
00035 
00036 * The work function, and the cleanup function, can make use of some amount of
00037   metadata that can be initialized before starting the threaded function.
00038 
00039 The general concept is that you have some section of code that can benefit
00040 from being threaded.  So, it is threaded, and the execution resumes in
00041 single-step function once the threaded section of the code completes.
00042 
00043 */
00044 
00045 struct cthreadinfo *cthread_init(
00046        unsigned,            /* Number of threads */
00047        unsigned,            /* Size of per-thread metadata */
00048        void (*)(void *),    /* The work function */
00049        void (*)(void *));   /* The cleanup function */
00050 
00051 /*
00052 
00053 cthread_init is used to initialize and start all threads.  cthread_init returns
00054 NULL if there was an error in setting up threading.  The first argument
00055 specifies the number of threads to start.  The second argument specifies how
00056 many bytes are there in per-thread metadata.  cthread_init will automatically
00057 allocate nthreads*metasize bytes internally.  The third argument is a pointer
00058 to the threaded function.  The fourth argument is a pointer to the cleanup
00059 function.
00060 
00061 cthread_init returns a handle pointer if threading has been succesfully
00062 set up.
00063 
00064 */
00065 
00066 void cthread_wait(struct cthreadinfo *);
00067 
00068 /*
00069 
00070 cthread_wait pauses until all current active threads have finished.  If there
00071 are any threads which are currently busy executed the work function or the
00072 cleanup function, cthread_wait pauses until they're done.  Then, cthread_wait
00073 kills all the threads, and deallocates all allocated resources for the
00074 handle
00075 
00076 */
00077 
00078 int cthread_go( struct cthreadinfo *,            /* Handle */
00079 
00080        void (*)(void *, void *),   /* Initialization function */
00081        void *);      /* Second arg to the initialization func */
00082 
00083 /*
00084 
00085 cthread_go finds an unused thread, and has it execute the work function, then
00086 the cleanup function.
00087 
00088 Both the work function and the cleanup function receive a pointer to the
00089 thread-specific metadata.  The second argument to cthread_go points to a
00090 function that will be used to initialize the thread-specific metadata before
00091 running the work function.  The first argument to this initialization function
00092 will be a pointer to the thread-specific metadata, which is stored internally
00093 by this library (associated with the handle).  When the initialization
00094 function returns, the work/cleanup functions are called with the same pointer.
00095 The third argument to cthread_go is passed as the second argument to the
00096 initialization function.
00097 
00098 If there are no available threads, cthread_go pauses until one becomes
00099 available.  cthread_go returns immediately after starting the thread, so
00100 upon return from cthread_go the work and cleanup functions are NOT guaranteed
00101 to have been called already.  cthread_go merely starts the thread, which will
00102 execute the work and the cleanup functions concurrently.
00103 
00104 When Posix threads are not available, cthread_go is a stub.  It calls the
00105 initialization function, then the work function, then the cleanup function,
00106 and then returns to the caller.  Hopefully, these semantics will be sufficient
00107 to carry out the necessary deed if threading is not available.
00108 */
00109 
00110 /*
00111 
00112 cthreadlock structure is used to implement locks.  Create a lock by calling
00113 cthread_lockcreate.  Destroy a lock by calling cthread_lockdelete.
00114 
00115 Calling cthread_lock obtains the lock specified by the first argument, calls
00116 the function specified by the second argument.  When the function returns,
00117 the lock is released.  The third argument is passed as the argument to the
00118 function.
00119 
00120 */
00121 
00122 struct cthreadlock *cthread_lockcreate(void);
00123 void cthread_lockdestroy(struct cthreadlock *);
00124 int cthread_lock(struct cthreadlock *, int (*)(void *), void *);
00125 
00126 #endif