int shlock_tryopen(shkey_t *key, int flags, shlock_t **lock_p) { shmap_t *lock_map = get_shlock_map(); shlock_t *lk; pid_t tid; #ifdef USE_LIBPTHREAD pthread_mutexattr_t attr; int err; #endif tid = gettid(); lk = shmap_get_ptr(lock_map, key); if (!lk) { lk = (shlock_t *)calloc(1, sizeof(shlock_t)); if (!lk) return (-1); shmap_set_ptr(lock_map, key, lk); #ifdef USE_LIBPTHREAD memset(&attr, 0, sizeof(attr)); if (!(flags & SHLK_PRIVATE)) { pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); } pthread_mutex_init(&lk->mutex, &attr); #endif } else if (lk->ref) { if ((flags & SHLK_PRIVATE)) { /* mutex is already locked. */ return (1); } if (tid != lk->tid) return (1); /* lock is not accessible from this thread. */ } if (!lk->ref || lk->tid != tid) { #ifdef USE_LIBPTHREAD /* returns an errno */ err = pthread_mutex_trylock(&lk->mutex); if (err == EBUSY) return (1); if (err) return (-1); #endif } /* assign variables after mutex is locked. */ lk->tid = tid; lk->ref++; *lock_p = lk; return (0); }
shlock_t *shlock_open(shkey_t *key, int flags) { shmap_t *lock_map = get_shlock_map(); shlock_t *lk; pid_t tid; #ifdef USE_LIBPTHREAD pthread_mutexattr_t attr; int err; #endif tid = gettid(); lk = shmap_get_ptr(lock_map, key); if (!lk) { lk = (shlock_t *)calloc(1, sizeof(shlock_t)); if (!lk) return (NULL); shmap_set_ptr(lock_map, key, lk); #ifdef USE_LIBPTHREAD memset(&attr, 0, sizeof(attr)); if (!(flags & SHLK_PRIVATE)) { pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); } pthread_mutex_init(&lk->mutex, &attr); #endif } #ifdef USE_LIBPTHREAD err = pthread_mutex_lock(&lk->mutex); if (err) { return (NULL); } #else /* bug: acts like trylock() instead of lock() .. need to introduce waiting psuedo-lock */ if (lk->ref) { if ((flags & SHLK_PRIVATE)) { /* mutex is already locked. */ return (NULL); } if (tid != lk->tid) { return (NULL); /* lock is not accessible from this thread. */ } } #endif /* assign variables after mutex is locked. */ lk->tid = tid; lk->ref++; return (lk); }
char *sexe_event_init(int e_type, const char *e_name) { static char key_str[256]; sexe_event_t *e; shkey_t *key; if (!event_map) { event_map = shmap_init(); } e = (sexe_event_t *)calloc(1, sizeof(sexe_event_t)); if (!e) return (SHERR_NOMEM); e->event_type = e_type; strncpy(e->mod_name, e_name, sizeof(e->mod_name) - 1); key = shkey_bin(e, sizeof(sexe_event_t)); memcpy(&e->reg_key, key, sizeof(shkey_t)); shmap_set_ptr(event_map, key, e); strncpy(key_str, shkey_hex(key), sizeof(key_str) - 1); shkey_free(&key); return (key_str); }