- LEAK_DETECTIVE activated
[strongswan.git] / Source / charon / event_queue.c
index 703a3a8..243186c 100644 (file)
@@ -166,6 +166,7 @@ static status_t get(private_event_queue_t *this, job_t **job)
        timeval_t current_time;
        event_t * next_event;
        int count;
        timeval_t current_time;
        event_t * next_event;
        int count;
+       int oldstate;
                
        pthread_mutex_lock(&(this->mutex));
        
                
        pthread_mutex_lock(&(this->mutex));
        
@@ -174,11 +175,21 @@ static status_t get(private_event_queue_t *this, job_t **job)
                this->list->get_count(this->list,&count);
                while(count == 0)
                {
                this->list->get_count(this->list,&count);
                while(count == 0)
                {
+                       /* add mutex unlock handler for cancellation, enable cancellation */
+                       pthread_cleanup_push((void(*)(void*))pthread_mutex_unlock, (void*)&(this->mutex));
+                       pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate);
+                       
                        pthread_cond_wait( &(this->condvar), &(this->mutex));
                        pthread_cond_wait( &(this->condvar), &(this->mutex));
+                                       
+                       /* reset cancellation, remove mutex-unlock handler (without executing) */
+                       pthread_setcancelstate(oldstate, NULL);
+                       pthread_cleanup_pop(0);
+               
                        this->list->get_count(this->list,&count);
                }
                        
                this->list->get_first(this->list,(void **) &next_event);
                        this->list->get_count(this->list,&count);
                }
                        
                this->list->get_first(this->list,(void **) &next_event);
+               
                gettimeofday(&current_time,NULL);
                long difference = time_difference(&current_time,&(next_event->time));
                if (difference <= 0)
                gettimeofday(&current_time,NULL);
                long difference = time_difference(&current_time,&(next_event->time));
                if (difference <= 0)
@@ -210,7 +221,7 @@ static status_t get(private_event_queue_t *this, job_t **job)
 /**
  * @brief implements function add of event_queue_t
  */
 /**
  * @brief implements function add of event_queue_t
  */
-static status_t add(private_event_queue_t *this, job_t *job, timeval_t time)
+static status_t add_absolute(private_event_queue_t *this, job_t *job, timeval_t time)
 {
        event_t *event = event_create(time,job);
        linked_list_element_t * current_list_element;
 {
        event_t *event = event_create(time,job);
        linked_list_element_t * current_list_element;
@@ -269,6 +280,7 @@ static status_t add(private_event_queue_t *this, job_t *job, timeval_t time)
                status = iterator->has_next(iterator,&has_next);
                if (status != SUCCESS)
                {
                status = iterator->has_next(iterator,&has_next);
                if (status != SUCCESS)
                {
+                       iterator->destroy(iterator);
                        break;
                }
                
                        break;
                }
                
@@ -284,8 +296,7 @@ static status_t add(private_event_queue_t *this, job_t *job, timeval_t time)
                        if (time_difference(&(event->time), &(current_event->time)) <= 0)
                        {
                                /* my event has to be fired before the current event in list */
                        if (time_difference(&(event->time), &(current_event->time)) <= 0)
                        {
                                /* my event has to be fired before the current event in list */
-                               status = this->list->insert_before(this->list,current_list_element,event);
-                               
+                               status = this->list->insert_before(this->list,current_list_element,event);                              
                                break;
                        }
                        
                                break;
                        }
                        
@@ -295,6 +306,7 @@ static status_t add(private_event_queue_t *this, job_t *job, timeval_t time)
                                break;
                        }
                }
                                break;
                        }
                }
+               iterator->destroy(iterator);
                break;
        }
 
                break;
        }
 
@@ -308,6 +320,23 @@ static status_t add(private_event_queue_t *this, job_t *job, timeval_t time)
        return status;          
 }
 
        return status;          
 }
 
+/**
+ * @brief implements function add of event_queue_t
+ */
+static status_t add_relative(event_queue_t *this, job_t *job, u_int32_t ms)
+{
+       timeval_t current_time;
+       timeval_t time;
+       int micros = ms * 1000;
+       
+       gettimeofday(&current_time, NULL);
+       
+       time.tv_usec = ((current_time.tv_usec + micros) % 1000000);
+       time.tv_sec = current_time.tv_sec + ((current_time.tv_usec + micros)/ 1000000);
+       
+       return this->add_absolute(this, job, time);
+}
+
 
 /**
  * @brief implements function destroy of event_queue_t
 
 /**
  * @brief implements function destroy of event_queue_t
@@ -360,7 +389,8 @@ event_queue_t *event_queue_create()
        
        this->public.get_count = (status_t (*) (event_queue_t *event_queue, int *count)) get_count;
        this->public.get = (status_t (*) (event_queue_t *event_queue, job_t **job)) get;
        
        this->public.get_count = (status_t (*) (event_queue_t *event_queue, int *count)) get_count;
        this->public.get = (status_t (*) (event_queue_t *event_queue, job_t **job)) get;
-       this->public.add = (status_t (*) (event_queue_t *event_queue, job_t *job, timeval_t time)) add;
+       this->public.add_absolute = (status_t (*) (event_queue_t *event_queue, job_t *job, timeval_t time)) add_absolute;
+       this->public.add_relative = (status_t (*) (event_queue_t *event_queue, job_t *job, u_int32_t ms)) add_relative;
        this->public.destroy = (status_t (*) (event_queue_t *event_queue)) event_queue_destroy;
        
        this->list = linked_list;
        this->public.destroy = (status_t (*) (event_queue_t *event_queue)) event_queue_destroy;
        
        this->list = linked_list;