FreeBSD Bugzilla – Attachment 165809 Details for
Bug 206396
Crash while concurrent POSIX semaphore access
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
Test code
thread_test.c (text/x-c), 5.33 KB, created by
Alexander Saprykin
on 2016-01-19 10:57:49 UTC
(
hide
)
Description:
Test code
Filename:
MIME Type:
Creator:
Alexander Saprykin
Created:
2016-01-19 10:57:49 UTC
Size:
5.33 KB
patch
obsolete
>#include <stdlib.h> >#include <stdio.h> >#include <time.h> >#include <string.h> >#include <pthread.h> >#include <unistd.h> > >#include <errno.h> >#include <fcntl.h> >#include <semaphore.h> > >static int semaphore_test_val = 10; > >typedef void * (*PUThreadFunc) (void *arg); > >#define P_SEM_SUFFIX "_p_sem_object" >#define P_SEM_ERROR_BUF_SIZE 255 > >typedef sem_t psem_hdl; > >#define P_SEM_INVALID_HDL SEM_FAILED > >/** Enum with #PSemaphore creation modes */ >typedef enum _PSemaphoreAccessMode { > P_SEM_ACCESS_OPEN = 0, /**< Open existing semaphore or create one with given value */ > P_SEM_ACCESS_CREATE = 1 /**< Create semaphore, reset to given value if exists */ >} PSemaphoreAccessMode; > >typedef struct _PSemaphore { > int sem_created; > char *platform_key; > psem_hdl *sem_hdl; > PSemaphoreAccessMode mode; > int init_val; >} PSemaphore; > >pthread_t >p_uthread_create_full (PUThreadFunc func, > void * data) >{ > pthread_attr_t attr; > pthread_t hdl; > > if (!func) > return NULL; > > if (pthread_attr_init (&attr) != 0) > return NULL; > > if (pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_JOINABLE) != 0) { > pthread_attr_destroy (&attr); > return NULL; > } > > pthread_attr_setscope (&attr, PTHREAD_SCOPE_SYSTEM); > > if (pthread_create (&hdl, &attr, func, data) != 0) { > pthread_attr_destroy (&attr); > return NULL; > } > > pthread_attr_destroy (&attr); > > return hdl; >} > >int >p_uthread_sleep (unsigned int msec) >{ > int result; > struct timespec time_req; > struct timespec time_rem; > > memset (&time_rem, 0, sizeof (struct timespec)); > > time_req.tv_nsec = (msec % 1000) * 1000000L; > time_req.tv_sec = (time_t) (msec / 1000); > > result = -1; > while (result != 0) { > if ((result = nanosleep (&time_req, &time_rem)) != 0) { > if (errno == EINTR) > time_req = time_rem; > else > return -1; > } > } > > return 0; >} > >static void >__p_semaphore_clean_handle (PSemaphore *sem) >{ > if (sem == NULL) > return; > > if (sem->sem_hdl != P_SEM_INVALID_HDL) > sem_close (sem->sem_hdl); > > if (sem->sem_hdl != P_SEM_INVALID_HDL && sem->sem_created) > sem_unlink (sem->platform_key); > > sem->sem_created = 0; > sem->sem_hdl = P_SEM_INVALID_HDL; >} > >static int >__p_semaphore_create_handle (PSemaphore *sem) >{ > if (sem == NULL || sem->platform_key == NULL) > return 0; > > /* Solaris may interrupt sem_open call */ > while ((sem->sem_hdl = sem_open (sem->platform_key, O_CREAT | O_EXCL, 0660, sem->init_val)) == P_SEM_INVALID_HDL > && errno == EINTR) > ; > > if (sem->sem_hdl == P_SEM_INVALID_HDL) > { > if (errno == EEXIST) { > if (sem->mode == P_SEM_ACCESS_CREATE) > sem_unlink (sem->platform_key); > > while ((sem->sem_hdl = sem_open (sem->platform_key, 0, 0, 0)) == P_SEM_INVALID_HDL > && errno == EINTR) > ; > } > } else > sem->sem_created = 1; > > if (sem->sem_hdl == P_SEM_INVALID_HDL) { > __p_semaphore_clean_handle (sem); > return 0; > } > > return 1; >} > >static void >p_semaphore_free (PSemaphore *sem) >{ > if (sem == NULL) > return; > > __p_semaphore_clean_handle (sem); > > if (sem->platform_key) > free (sem->platform_key); > > free (sem); >} > >static PSemaphore * >p_semaphore_new (const char *name, int init_val, PSemaphoreAccessMode mode) >{ > PSemaphore *ret; > char *new_name; > > if (name == NULL || init_val < 0) > return NULL; > > if ((ret = malloc (sizeof (PSemaphore))) == NULL) > return NULL; > > memset (ret, 0, sizeof (PSemaphore)); > > if ((new_name = malloc (strlen (name) + strlen (P_SEM_SUFFIX) + 2)) == NULL) { > free (ret); > return NULL; > } > > strcpy (new_name, "/"); > strcat (new_name, name); > strcat (new_name, P_SEM_SUFFIX); > > ret->platform_key = new_name; > ret->init_val = init_val; > ret->mode = mode; > > if (!__p_semaphore_create_handle (ret)) { > p_semaphore_free (ret); > return NULL; > } > > return ret; >} > >void >p_semaphore_take_ownership (PSemaphore *sem) >{ > if (sem == NULL) > return; > > sem->sem_created = 1; >} > >int >p_semaphore_acquire (PSemaphore *sem) >{ > int res; > > if (sem == NULL) > return 0; > > while ((res = sem_wait (sem->sem_hdl)) == -1 && errno == EINTR) > ; > > return res == 0 ? 1 : 0; >} > >int >p_semaphore_release (PSemaphore *sem) >{ > if (sem == NULL) > return 0; > > return sem_post (sem->sem_hdl) == 0 ? 1 : 0; >} > >static void * semaphore_test_thread (void *arg) >{ > PSemaphore *sem; > int i; > > sem = p_semaphore_new ("p_semaphore_test_object", 1, P_SEM_ACCESS_OPEN); > > if (sem == NULL) > pthread_exit ((void *) (1)); > > for (i = 0; i < 1000; ++i) { > if (!p_semaphore_acquire (sem)) { > p_semaphore_free (sem); > pthread_exit ((void *) (1)); > } > > if (semaphore_test_val == 10) > --semaphore_test_val; > else { > p_uthread_sleep (1); > ++semaphore_test_val; > } > > if (!p_semaphore_release (sem)) { > p_semaphore_free (sem); > pthread_exit ((void *) (1)); > } > } > > p_semaphore_free (sem); > pthread_exit ((void *) (0)); >} > >int main (int argc, char **argv) >{ > PSemaphore *sem; > pthread_t thr1, thr2; > void * ret; > > thr1 = p_uthread_create_full ((PUThreadFunc) semaphore_test_thread, NULL); > > thr2 = p_uthread_create_full ((PUThreadFunc) semaphore_test_thread, NULL); > > pthread_join (thr1, &ret); > pthread_join (thr2, &ret); > > sem = p_semaphore_new ("p_semaphore_test_object", 1, P_SEM_ACCESS_OPEN); > p_semaphore_take_ownership (sem); > p_semaphore_free (sem); > > printf ("Done OK.\n"); > > return 0; >}
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 206396
: 165809