]> rtime.felk.cvut.cz Git - frescor/fosa.git/blobdiff - src_aquosa/fosa_threads_and_signals.c
Allow for mutexes and condvars to be shared among different processes.
[frescor/fosa.git] / src_aquosa / fosa_threads_and_signals.c
index 3f64a674dfd2c883ba99b58e0ec20e7b550bcbea..03e31160e9c69f305f4c32b842db9d9048554086 100644 (file)
@@ -73,20 +73,20 @@ static pthread_mutex_t key_lock;
 /* Initialize the keys data structure */
 int init_keys()
 {
-       int i, error;
+       int i, ret;
        pthread_mutexattr_t attr;
 
        for(i = 0; i < FOSA_MAX_KEYS; i++)
                key_in_use[i] = false;
 
-       if ((error = pthread_mutexattr_init(&attr)) != 0)
-               return error;
+       ret = pthread_mutexattr_init(&attr);
+       if (ret) return errno;
 
-       if ((error = pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT)) != 0)
-               return error;
+       ret = pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT);
+       if (ret) return errno;
 
-       if ((error = pthread_mutex_init(&key_lock,&attr)) != 0)
-               return error;
+       ret = pthread_mutex_init(&key_lock,&attr);
+       if (ret) return errno;
 
        return 0;
 }
@@ -279,27 +279,30 @@ int fosa_thread_create(fosa_thread_id_t *tid,
  **/
 int fosa_key_create(int *key)
 {
-       int i, error = 0;
+       int i, ret;
        bool found = false;
 
-       if ((error = pthread_mutex_lock(&key_lock)) != 0)
-               return error;
+       ret = pthread_mutex_lock(&key_lock);
+       if (ret) return ret;
 
        /* find an unused key */
        for (i = 0; i < FOSA_MAX_KEYS; i++) {
                if (!key_in_use[i]) {
+                       ret = pthread_key_create(&(key_list[i]), NULL);
+                       if (ret) return ret;
+
                        *key = i;
                        key_in_use[i] = true;
-                       error = pthread_key_create(&(key_list[i]), NULL);
                        found = true;
+
                        break;
                }
        }
 
-       if ((error = pthread_mutex_unlock(&key_lock))!= 0)
-               return error;
+       ret = pthread_mutex_unlock(&key_lock);
+       if (ret) return ret;
 
-       return (!found ? FOSA_EINVAL : error);
+       return (!found ? FOSA_EINVAL : ret);
 }
 
 /**
@@ -314,16 +317,18 @@ int fosa_key_create(int *key)
  **/
 int fosa_key_destroy(int key)
 {
-       int error;
+       int ret;
 
-       if ((error = pthread_mutex_lock(&key_lock)) != 0)
-               return error;
+       ret = pthread_mutex_lock(&key_lock);
+       if (ret) return ret;
 
-       if ((error = pthread_key_delete(key_list[key])) != 0)
-               key_in_use[key]=false;
+       ret = pthread_key_delete(key_list[key]);
+       if (ret) return ret;
 
-       if ((error = pthread_mutex_unlock(&key_lock)) != 0)
-               return error;
+       key_in_use[key]=false;
+
+       ret = pthread_mutex_unlock(&key_lock);
+       if (ret) return ret;
 
        return 0;
 }
@@ -347,11 +352,15 @@ int fosa_key_destroy(int key)
                                   fosa_thread_id_t tid,
                                   const void * value)
 {
+       int ret;
+
        /* only POSIX threads can have specific data */
        if (!__fosa_check_thread(&tid))
-               return EINVAL;
+               return FOSA_EINVAL;
 
-       return pthread_setspecific(key_list[key], value);
+       ret = pthread_setspecific(key_list[key], value);
+
+       return ret ? ret : 0;
 }
 
 /**
@@ -376,10 +385,9 @@ int fosa_thread_get_specific_data(int key,
        if (!__fosa_check_thread(&tid))
                return EINVAL;
 
-       if ((value = pthread_getspecific(key_list[key])) != NULL)
-               return EINVAL;
-       else
-               return 0;
+       value = pthread_getspecific(key_list[key]);
+
+       return !value ? FOSA_EINVAL : 0;
 }
 
 /******************************************************************
@@ -400,7 +408,11 @@ int fosa_thread_get_specific_data(int key,
  **/
 int fosa_get_priority_max()
 {
-       return sched_get_priority_max(SCHED_RR);
+       int ret;
+
+       ret = sched_get_priority_max(SCHED_RR);
+
+       return ret ? errno : 0;
 }
 
 /**
@@ -410,7 +422,11 @@ int fosa_get_priority_max()
  **/
 int fosa_get_priority_min()
 {
-       return sched_get_priority_min(SCHED_RR);
+       int ret;
+
+       ret = sched_get_priority_min(SCHED_RR);
+
+       return ret ? errno : 0;
 }
 
 /**
@@ -431,12 +447,12 @@ int fosa_get_priority_min()
  **/
 int fosa_thread_attr_set_prio(fosa_thread_attr_t *attr, int prio)
 {
-       int error;
+       int ret;
        struct sched_param param;
 
        param.sched_priority = prio;
-       if ((error = pthread_attr_setschedpolicy(attr, SCHED_RR)) == 0)
-               return error;
+       ret = pthread_attr_setschedpolicy(attr, SCHED_RR);
+       if (ret) return ret;
 
        return pthread_attr_setschedparam(attr, &param);
 }
@@ -453,13 +469,15 @@ int fosa_thread_attr_set_prio(fosa_thread_attr_t *attr, int prio)
  **/
 int fosa_thread_attr_get_prio(const fosa_thread_attr_t *attr, int *prio)
 {
-       int error;
+       int ret;
        struct sched_param param;
 
-       if ((error = pthread_attr_getschedparam(attr, &param)) == 0)
-               *prio = param.sched_priority;
+       ret = pthread_attr_getschedparam(attr, &param);
+       if (ret) return ret;
+
+       *prio = param.sched_priority;
 
-       return error;
+       return 0;
 }
 
 /**
@@ -477,10 +495,14 @@ int fosa_thread_attr_get_prio(const fosa_thread_attr_t *attr, int *prio)
  **/
 int fosa_thread_set_prio(fosa_thread_id_t tid, int prio)
 {
+       int ret;
        struct sched_param param;
 
        param.sched_priority = prio;
-       return sched_setscheduler(0, SCHED_RR, &param);
+
+       ret = sched_setscheduler(0, SCHED_RR, &param);
+
+       return ret ? errno : 0;
 }
 
 /**
@@ -501,7 +523,7 @@ int fosa_thread_get_prio(fosa_thread_id_t tid, int *prio)
        ret = sched_getparam(0, &param);
        *prio = param.sched_priority;
 
-       return ret;
+       return ret ? errno : 0;
 }
 
 /*******************************************************************
@@ -537,13 +559,13 @@ int fosa_thread_get_prio(fosa_thread_id_t tid, int *prio)
  **/
 int fosa_set_accepted_signals(fosa_signal_t set[], int size)
 {
-       int i, error;
+       int i, ret;
        fosa_thread_id_t self;
        sigset_t sigset;
        struct sigaction action;
 
-       if ((error = sigemptyset(&sigset)) != 0)
-               return error;
+       ret = sigemptyset(&sigset);
+       if (ret) goto err;
 
        action.sa_handler = SIG_DFL;
        action.sa_mask = sigset;
@@ -551,17 +573,24 @@ int fosa_set_accepted_signals(fosa_signal_t set[], int size)
        action.sa_sigaction = NULL;
 
        for (i = 0; i < size; i++) {
-               if ((error = sigaddset(&sigset, set[i])) != 0)
-                       return error;
-               if ((error = sigaction(set[i], &action, NULL)) != 0)
-                       return error;
+               ret = sigaddset(&sigset, set[i]);
+               if (ret) goto err;
+               ret = sigaction(set[i], &action, NULL);
+               if (ret) goto err;
        }
 
        self = fosa_thread_self();
-       if (__fosa_check_thread(&self))
-               return pthread_sigmask(SIG_BLOCK, &sigset, NULL);
-       else
-               return sigprocmask(SIG_BLOCK, &sigset, NULL);
+       if (__fosa_check_thread(&self)) {
+               ret = pthread_sigmask(SIG_BLOCK, &sigset, NULL);
+               if (ret) return ret;
+       } else {
+               ret = sigprocmask(SIG_BLOCK, &sigset, NULL);
+               if (ret) goto err;
+       }
+
+       return 0;
+err:
+       return errno;
 }
 
 /**
@@ -601,12 +630,13 @@ int fosa_signal_queue(fosa_signal_t signal,
                      fosa_signal_info_t info,
                      fosa_thread_id_t receiver)
 {
-       int error;
+       int ret;
        timer_t fake_timer;
        struct itimerspec fake_time;
        struct sigevent fake_event;
 
-       timer_create(CLOCK_MONOTONIC, &fake_event, &fake_timer);
+       ret = timer_create(FOSA_CLOCK_REALTIME, &fake_event, &fake_timer);
+       if (ret) goto err;
 
         fake_time.it_value.tv_sec = fake_time.it_value.tv_nsec = 0;
         fake_time.it_interval.tv_sec = fake_time.it_interval.tv_nsec = 0;
@@ -615,10 +645,18 @@ int fosa_signal_queue(fosa_signal_t signal,
        fake_event.sigev_value.sival_int = info.sival_int;
         fake_event._sigev_un._tid = receiver.linux_tid;
 
-        error = timer_settime(fake_timer, TIMER_ABSTIME, &fake_time, NULL);
-       timer_delete(fake_timer);
+        ret = timer_settime(fake_timer, TIMER_ABSTIME, &fake_time, NULL);
+       if (ret) {
+               timer_delete(fake_timer);
+               goto err;
+       }
 
-       return error;
+       ret = timer_delete(fake_timer);
+       if (ret) goto err;
+
+       return 0;
+err:
+       return errno;
 }
 
 /**
@@ -649,19 +687,20 @@ int fosa_signal_wait(fosa_signal_t set[], int size,
                     fosa_signal_t *signal_received,
                     fosa_signal_info_t *info)
 {
-       int i, error;
+       int i, ret;
        sigset_t sigset;
        siginfo_t siginfo;
 
-       if ((error = sigemptyset(&sigset)) != 0)
-               return error;
+       ret = sigemptyset(&sigset);
+       if (ret) goto err;
 
-       for (i = 0; i < size; i++)
-               if ((error = sigaddset(&sigset,set[i])) != 0)
-                       return error;
+       for (i = 0; i < size; i++) {
+               ret = sigaddset(&sigset,set[i]);
+               if (ret) goto err;
+       }
 
-       if ((error = sigwaitinfo(&sigset, &siginfo)) != 0)
-               return error;
+       ret = sigwaitinfo(&sigset, &siginfo);
+       if (ret) goto err;
 
        if (info != NULL && signal_received != NULL)
                *signal_received = siginfo.si_signo;
@@ -669,6 +708,8 @@ int fosa_signal_wait(fosa_signal_t set[], int size,
                *info = (fosa_signal_info_t) siginfo.si_value.sival_int;
 
        return 0;
+err:
+       return errno;
 }
 
 /**
@@ -695,19 +736,20 @@ int fosa_signal_timedwait(fosa_signal_t set[], int size,
                          fosa_signal_info_t *info,
                          const struct timespec *timeout)
 {
-       int i, error;
+       int i, ret;
        sigset_t signalset;
        siginfo_t siginfo;
 
-       if ((error = sigemptyset(&signalset)) != 0)
-               return error;
+       ret = sigemptyset(&signalset);
+       if (ret) goto err;
 
-       for (i = 0; i < size; i++)
-               if ((error = sigaddset(&signalset,set[i])) != 0)
-                       return error;
+       for (i = 0; i < size; i++) {
+               ret = sigaddset(&signalset,set[i]);
+               if (ret) goto err;
+       }
 
-       if ((error = sigtimedwait(&signalset,&siginfo,timeout)) != 0)
-               return error;
+       ret = sigtimedwait(&signalset,&siginfo,timeout);
+       if (ret) goto err;
 
        if (signal_received != NULL)
                *signal_received = siginfo.si_signo;
@@ -715,5 +757,7 @@ int fosa_signal_timedwait(fosa_signal_t set[], int size,
                *info = (fosa_signal_info_t) siginfo.si_value.sival_int;
 
        return 0;
+err:
+       return errno;
 }