added thread initialization/deinitialization hooks
authorMartin Willi <martin@strongswan.org>
Tue, 2 Oct 2007 11:23:14 +0000 (11:23 -0000)
committerMartin Willi <martin@strongswan.org>
Tue, 2 Oct 2007 11:23:14 +0000 (11:23 -0000)
moved empty_enumerator to a public implementation

src/manager/Makefile.am
src/manager/database.c
src/manager/lib/dispatcher.c
src/manager/lib/dispatcher.h
src/manager/lib/enumerator.h
src/manager/main.c

index 3547aec..6380718 100644 (file)
@@ -15,7 +15,7 @@ lib_LTLIBRARIES = libappserv.la
 libappserv_la_SOURCES = \
 lib/context.h lib/dispatcher.c lib/request.h lib/session.h \
 lib/controller.h lib/dispatcher.h lib/request.c lib/session.c \
-lib/xml.h lib/xml.c lib/enumerator.h
+lib/xml.h lib/xml.c lib/enumerator.h lib/enumerator.c
 
 libappserv_la_LIBADD = $(top_builddir)/src/libstrongswan/libstrongswan.la -lfcgi -lpthread -lneo_cgi -lneo_cs -lneo_utl ${xml_LIBS}
 
index ebd9fa9..101e0c7 100644 (file)
@@ -77,25 +77,6 @@ static enumerator_t *db_enumerator_create(bool(*enumerate)(db_enumerator_t*,void
 }
 
 /**
- * enumerator function for empty enumerator
- */
-static bool empty_enumerate(enumerator_t *enumerator, void *item, ...)
-{
-       return FALSE;
-}
-
-/**
- * create an empty enumerator
- */
-static enumerator_t* empty_enumerator_create()
-{
-       enumerator_t *this = malloc_thing(enumerator_t);
-       this->enumerate = empty_enumerate;
-       this->destroy = (void*)free;
-       return this;
-}
-
-/**
  * Implementation of database_t.login.
  */
 static int login(private_database_t *this, char *username, char *password)
@@ -170,7 +151,7 @@ static enumerator_t* create_gateway_enumerator(private_database_t *this, int use
                }
                sqlite3_finalize(stmt);
        }
-       return empty_enumerator_create();
+       return enumerator_create_empty();
 }
 
 /**
index 5ce5523..df669ce 100644 (file)
@@ -88,6 +88,26 @@ struct private_dispatcher_t {
         * user param to context constructor
         */
        void *param;
+       
+       /**
+        * thread specific initialization handler
+        */
+       void (*init)(void *param);
+       
+       /**
+        * argument to pass to thread intiializer
+        */
+       void *init_param;
+       
+       /**
+        * thread specific deinitialization handler
+        */
+       void (*deinit)(void *param);
+       
+       /**
+        * param tho thread specific deinitialization handler
+        */
+       void *deinit_param;
 };
 
 typedef struct {
@@ -172,13 +192,12 @@ static void add_controller(private_dispatcher_t *this,
 }
 
 /**
- * Dispatch 
+ * Actual dispatching code 
  */
 static void dispatch(private_dispatcher_t *this)
 {
        FCGX_Request fcgi_req;
        
-       pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
        if (FCGX_InitRequest(&fcgi_req, this->fd, 0) == 0)
        {
                while (TRUE)
@@ -274,16 +293,44 @@ static void dispatch(private_dispatcher_t *this)
 }
 
 /**
+ * Setup thread and start dispatching 
+ */
+static void start_dispatching(private_dispatcher_t *this)
+{
+       pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
+       if (this->init)
+       {
+               this->init(this->init_param);
+       }
+       if (this->deinit)
+       {
+               pthread_cleanup_push(this->deinit, this->deinit_param);
+               dispatch(this);
+               pthread_cleanup_pop(1);
+       }
+       else
+       {
+               dispatch(this);
+       }
+}
+
+/**
  * Implementation of dispatcher_t.run.
  */
-static void run(private_dispatcher_t *this, int threads)
+static void run(private_dispatcher_t *this, int threads,
+                               void(*init)(void *param), void *init_param,
+                               void(*deinit)(void *param), void *deinit_param)
 {
+       this->init = init;
+       this->init_param = init_param;
+       this->deinit = deinit;
+       this->deinit_param = deinit_param;
        this->thread_count = threads;
        this->threads = malloc(sizeof(pthread_t) * threads);
        while (threads)
        {
                if (pthread_create(&this->threads[threads - 1],
-                                                  NULL, (void*)dispatch, this) == 0)
+                                                  NULL, (void*)start_dispatching, this) == 0)
                {
                        threads--;
                }
@@ -331,7 +378,7 @@ dispatcher_t *dispatcher_create(char *socket, int timeout,
        private_dispatcher_t *this = malloc_thing(private_dispatcher_t);
 
        this->public.add_controller = (void(*)(dispatcher_t*, controller_constructor_t, void*))add_controller;
-       this->public.run = (void(*)(dispatcher_t*, int threads))run;
+       this->public.run = (void(*)(dispatcher_t*, int threads,void(*)(void *),void *,void(*)(void *),void *))run;
        this->public.waitsignal = (void(*)(dispatcher_t*))waitsignal;
        this->public.destroy = (void(*)(dispatcher_t*))destroy;
        
index d047054..2748378 100644 (file)
@@ -52,9 +52,20 @@ struct dispatcher_t {
        /**
         * @brief Start with dispatching.
         *
+        * It may be necessary to call per-thread initialization functions. 
+        * If init is not NULL, the handler is called right after thread
+        * creation (by the created thread) and the deinit function is called
+        * before the thread gets destroyed (again by the thread itself).
+        *
         * @param thread                number of dispatching threads
+        * @param init                  thread specific initialization function, or NULL
+        * @param init_param    param to pass to init function
+        * @param deinit                thread dpecific deinitialization function, or NULL
+        * @param deinit_param  param to pass to deinit function
         */
-       void (*run)(dispatcher_t *this, int threads);
+       void (*run)(dispatcher_t *this, int threads,
+                               void(*init)(void *param), void *init_param,
+                               void(*deinit)(void *param), void *deinit_param);
        
        /**
         * @brief Wait for a relevant signal action.
index 7321e21..df1d782 100644 (file)
@@ -35,11 +35,13 @@ struct enumerator_t {
        /**
         * @brief Enumerate collection.
         *
-        * @param item          first enumerated item
-        * @param ...           additional items enumerated, depending in implementation
-        * @return                      TRUE if pointers returned
+        * The enumerate function takes a variable argument list containing 
+        * pointers where the enumerated values get written.
+        *
+        * @param ...   variable list of enumerated items, implementation dependant
+        * @return              TRUE if pointers returned
         */
-       bool (*enumerate)(enumerator_t *this, void *item, ...);
+       bool (*enumerate)(enumerator_t *this, ...);
                
        /**
      * @brief Destroy a enumerator instance.
@@ -47,4 +49,9 @@ struct enumerator_t {
     void (*destroy)(enumerator_t *this);
 };
 
+/**
+ * @brief Create an enumerator which enumerates over nothing
+ */
+enumerator_t* enumerator_create_empty();
+
 #endif /* ENUMERATOR_H_ */
index 45e4b2f..bbe07cb 100644 (file)
@@ -56,7 +56,7 @@ int main (int arc, char *argv[])
        dispatcher->add_controller(dispatcher, gateway_controller_create, NULL);
        dispatcher->add_controller(dispatcher, auth_controller_create, NULL);
        
-       dispatcher->run(dispatcher, THREADS);
+       dispatcher->run(dispatcher, THREADS, NULL, NULL, NULL, NULL);
        
        dispatcher->waitsignal(dispatcher);