diff --git a/lock.c b/lock.c index 29bebb15..3c55a68c 100644 --- a/lock.c +++ b/lock.c @@ -245,6 +245,47 @@ pid_t uwsgi_lock_fast_check(struct uwsgi_lock_item *uli) { pid_t uwsgi_rwlock_fast_check(struct uwsgi_lock_item *uli) { return uwsgi_lock_fast_check(uli); } +#elif defined(UWSGI_LOCK_USE_POSIX_SEM) + +#define UWSGI_LOCK_SIZE sizeof(sem_t) +#define UWSGI_RWLOCK_SIZE sizeof(sem_t) +#define UWSGI_LOCK_ENGINE_NAME "POSIX semaphores" + +#include + +struct uwsgi_lock_item *uwsgi_lock_fast_init(char *id) { + struct uwsgi_lock_item *uli = uwsgi_register_lock(id, 0); + sem_init((sem_t*) uli->lock_ptr, 1, 1); + uli->can_deadlock = 1; + return uli; +} + +struct uwsgi_lock_item *uwsgi_rwlock_fast_init(char *id) { return uwsgi_lock_fast_init(id) ;} + +void uwsgi_lock_fast(struct uwsgi_lock_item *uli) { + sem_wait((sem_t *) uli->lock_ptr); + uli->pid = uwsgi.mypid; +} + +void uwsgi_unlock_fast(struct uwsgi_lock_item *uli) { + sem_post((sem_t*) uli->lock_ptr); + uli->pid = 0; +} + +pid_t uwsgi_lock_fast_check(struct uwsgi_lock_item *uli) { + if (sem_trywait((sem_t *) uli->lock_ptr) == 0) { + sem_post((sem_t*) uli->lock_ptr); + return 0; + } + return uli->pid; +} + +pid_t uwsgi_rwlock_fast_check(struct uwsgi_lock_item *uli) { return uwsgi_lock_fast_check(uli); } +void uwsgi_rlock_fast(struct uwsgi_lock_item *uli) { uwsgi_lock_fast(uli);} +void uwsgi_wlock_fast(struct uwsgi_lock_item *uli) { uwsgi_lock_fast(uli);} +void uwsgi_rwunlock_fast(struct uwsgi_lock_item *uli) { uwsgi_unlock_fast(uli); } + + #elif defined(UWSGI_LOCK_USE_OSX_SPINLOCK) #define UWSGI_LOCK_ENGINE_NAME "OSX spinlocks" diff --git a/uwsgiconfig.py b/uwsgiconfig.py index 54d7cc00..3954b1b0 100644 --- a/uwsgiconfig.py +++ b/uwsgiconfig.py @@ -415,16 +415,22 @@ class uConf(object): if uwsgi_os == 'Linux' or uwsgi_os == 'SunOS': locking_mode = 'pthread_mutex' # FreeBSD umtx is still not ready for process shared locking - #elif uwsgi_os == 'FreeBSD': - # locking_mode = 'umtx' + # starting from FreeBSD 9 posix semaphores can be shared between processes + elif uwsgi_os == 'FreeBSD': + try: + fbsd_major = int(uwsgi_os_k.split('.')[0]) + if fbsd_major >= 9: + locking_mode = 'posix_sem' + except: + pass elif uwsgi_os == 'Darwin': locking_mode = 'osx_spinlock' if locking_mode == 'pthread_mutex': self.cflags.append('-DUWSGI_LOCK_USE_MUTEX') # FreeBSD umtx is still not ready for process shared locking - #elif locking_mode == 'umtx': - # self.cflags.append('-DUWSGI_LOCK_USE_UMTX') + elif locking_mode == 'posix_sem': + self.cflags.append('-DUWSGI_LOCK_USE_POSIX_SEM') elif locking_mode == 'osx_spinlock': self.cflags.append('-DUWSGI_LOCK_USE_OSX_SPINLOCK')