static apr_status_t proc_mutex_proc_pthread_tryacquire(apr_proc_mutex_t *mutex) { apr_status_t rv; if ((rv = pthread_mutex_trylock(mutex->pthread_interproc))) { #ifdef HAVE_ZOS_PTHREADS rv = errno; #endif if (rv == EBUSY) { return APR_EBUSY; } #ifdef HAVE_PTHREAD_MUTEX_ROBUST /* Okay, our owner died. Let's try to make it consistent again. */ if (rv == EOWNERDEAD) { pthread_mutex_consistent_np(mutex->pthread_interproc); rv = APR_SUCCESS; } else return rv; #else return rv; #endif } mutex->curr_locked = 1; return rv; }
/* * Unlocks a mutex and logs any errors. */ int ipc_mutex_unlock(pthread_mutex_t *mutex) { int error; error = pthread_mutex_unlock(mutex); #ifdef HAVE_PTHREAD_MUTEXATTR_SETROBUST_NP if (error == EOWNERDEAD) { if (pthread_mutex_consistent_np(mutex) != 0) { filebench_log(LOG_FATAL, "mutex make consistent " "failed: %s", strerror(error)); return (-1); } return (0); } #endif /* HAVE_PTHREAD_MUTEXATTR_SETROBUST_NP */ if (error != 0) { filebench_log(LOG_FATAL, "mutex unlock failed: %s", strerror(error)); } return (error); }
bool PIpcBuffer::trylock(pthread_mutex_t* mutex, int& lockCount) { if (lockCount) { lockCount++; return true; } int ret = pthread_mutex_trylock(mutex); //printf("PIpcBuffer::trylock: %d, %p, %d\n", m_key, mutex, ret); if (ret != 0) { if (ret == EOWNERDEAD) pthread_mutex_consistent_np(mutex); else if (ret == EBUSY) { return false; } else { g_critical("%s: %s", __PRETTY_FUNCTION__, strerror(ret)); return false; } } lockCount++; return true; }
int main(void) { FILE * fp; void * poSharedMem = getSharedMemPtr(); GlobalMutex = (pthread_mutex_t *)poSharedMem; pthread_once_t * pOnce = (pthread_once_t *)( ((char *)poSharedMem) + sizeof(pthread_mutex_t) ); pthread_once(pOnce, sharedMemoryMutexInit); if (GlobalMutex == NULL) { return 0; } int mutexLockResult; for (int i =0; i < 100000; i ++) { mutexLockResult = pthread_mutex_lock(GlobalMutex); if (0 == mutexLockResult) { fp = fopen("MutextestFile.txt", "r+"); if (NULL != fp) { fseek(fp, 0, SEEK_END); fprintf(fp, "%4d - ", i+1); fprintf(fp, myLine); fclose(fp); fp = NULL; } pthread_mutex_unlock(GlobalMutex); } else if (EOWNERDEAD == mutexLockResult) { fp = fopen("MutextestFile.txt", "r+"); if (NULL != fp) { fseek(fp, 0, SEEK_END); fprintf(fp, "%4d - ", i+1); fprintf(fp, myLine); fclose(fp); fp = NULL; } pthread_mutex_consistent_np(GlobalMutex); pthread_mutex_unlock(GlobalMutex); } } if(NULL != GlobalMutex) { detatchFromSharedMem(GlobalMutex); } }
void recover(void) { printf("\n %s: \n",__func__); printf("\n Performing Recovery by Thread : %ld \n",pthread_self()); /* erase owner record */ pthread_mutex_consistent_np(&mutex); /* reset shared data to valid state before unlocking mutex */ pthread_mutex_unlock(&mutex); printf("\n Recovery completed by Thread : %ld \n",pthread_self()); pthread_mutex_lock(&mutex); }
void uwsgi_lock_fast(struct uwsgi_lock_item *uli) { #ifdef EOWNERDEAD if (pthread_mutex_lock((pthread_mutex_t *) uli->lock_ptr) == EOWNERDEAD) { uwsgi_log("[deadlock-detector] a process holding a robust mutex died. recovering...\n"); pthread_mutex_consistent_np((pthread_mutex_t *) uli->lock_ptr); } #else pthread_mutex_lock((pthread_mutex_t *) uli->lock_ptr); #endif uli->pid = uwsgi.mypid; }
static apr_status_t proc_mutex_proc_pthread_acquire(apr_proc_mutex_t *mutex) { apr_status_t rv; if ((rv = pthread_mutex_lock(mutex->pthread_interproc))) { #ifdef PTHREAD_SETS_ERRNO rv = errno; #endif #ifdef HAVE_PTHREAD_MUTEXATTR_SETROBUST_NP /* Okay, our owner died. Let's try to make it consistent again. */ if (rv == EOWNERDEAD) { pthread_mutex_consistent_np(mutex->pthread_interproc); } else return rv; #else return rv; #endif } mutex->curr_locked = 1; return APR_SUCCESS; }
static int do_test (void) { #ifdef PREPARE_TMO PREPARE_TMO; #endif pthread_mutexattr_t a; if (pthread_mutexattr_init (&a) != 0) { puts ("mutexattr_init failed"); return 1; } if (pthread_mutexattr_setrobust_np (&a, 1) != 0) { puts ("mutexattr_setrobust failed"); return 1; } #ifdef ENABLE_PI printf("ENABLE_PI"); if (pthread_mutexattr_setprotocol (&a, PTHREAD_PRIO_INHERIT) != 0) { puts ("pthread_mutexattr_setprotocol failed"); return 1; } else { int e = pthread_mutex_init (&m1, &a); if (e == ENOTSUP) { puts ("PI robust mutexes not supported"); return 0; } else if (e != 0) { puts ("mutex_init m1 failed"); return 1; } pthread_mutex_destroy (&m1); } #endif #ifndef NOT_CONSISTENT if (pthread_mutex_init (&m1, &a) != 0) { puts ("mutex_init m1 failed"); return 1; } if (pthread_mutex_init (&m2, &a) != 0) { puts ("mutex_init m2 failed"); return 1; } #endif if (pthread_barrier_init (&b, NULL, 2) != 0) { puts ("barrier_init failed"); return 1; } long int round =1; for ( round = 1; round < 5; ++round) { #ifdef NOT_CONSISTENT if (pthread_mutex_init (&m1 , &a) != 0) { puts ("mutex_init m1 failed"); return 1; } if (pthread_mutex_init (&m2 , &a) != 0) { puts ("mutex_init m2 failed"); return 1; } #endif pthread_t th; if (pthread_create (&th, NULL, tf, (void *) round) != 0) { printf ("%ld: create failed\n", round); return 1; } int e = pthread_barrier_wait (&b); if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD) { printf ("%ld: parent: 1st barrier_wait failed\n", round); return 1; } if (pthread_cancel (th) != 0) { printf ("%ld: cancel failed\n", round); return 1; } e = pthread_barrier_wait (&b); if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD) { printf ("%ld: parent: 2nd barrier_wait failed\n", round); return 1; } #ifndef AFTER_JOIN if (round & 1) #endif { void *res; if (pthread_join (th, &res) != 0) { printf ("%ld: join failed\n", round); return 1; } if (res != PTHREAD_CANCELED) { printf ("%ld: thread not canceled\n", round); return 1; } } e = LOCK (&m1); if (e == 0) { printf ("%ld: parent: mutex_lock m1 succeeded\n", round); return 1; } if (e != EOWNERDEAD) { printf ("%ld: parent: mutex_lock m1 returned wrong code\n", round); return 1; } e = LOCK (&m2); if (e == 0) { printf ("%ld: parent: mutex_lock m2 succeeded\n", round); return 1; } if (e != EOWNERDEAD) { printf ("%ld: parent: mutex_lock m2 returned wrong code\n", round); return 1; } #ifndef AFTER_JOIN if ((round & 1) == 0) { void *res; if (pthread_join (th, &res) != 0) { printf ("%ld: join failed\n", round); return 1; } if (res != PTHREAD_CANCELED) { printf ("%ld: thread not canceled\n", round); return 1; } } #endif #ifndef NOT_CONSISTENT e = pthread_mutex_consistent_np (&m1); if (e != 0) { printf ("%ld: mutex_consistent m1 failed with error %d\n", round, e); return 1; } e = pthread_mutex_consistent_np (&m2); if (e != 0) { printf ("%ld: mutex_consistent m2 failed with error %d\n", round, e); return 1; } #endif e = pthread_mutex_unlock (&m1); if (e != 0) { printf ("%ld: mutex_unlock m1 failed with %d\n", round, e); return 1; } e = pthread_mutex_unlock (&m2); if (e != 0) { printf ("%ld: mutex_unlock m2 failed with %d\n", round, e); return 1; } #ifdef NOT_CONSISTENT e = LOCK (&m1); if (e == 0) { printf ("%ld: locking inconsistent mutex m1 succeeded\n", round); return 1; } if (e != ENOTRECOVERABLE) { printf ("%ld: locking inconsistent mutex m1 failed with error %d\n", round, e); return 1; } if (pthread_mutex_destroy (&m1) != 0) { puts ("mutex_destroy m1 failed"); return 1; } e = LOCK (&m2); if (e == 0) { printf ("%ld: locking inconsistent mutex m2 succeeded\n", round); return 1; } if (e != ENOTRECOVERABLE) { printf ("%ld: locking inconsistent mutex m2 failed with error %d\n", round, e); return 1; } if (pthread_mutex_destroy (&m2) != 0) { puts ("mutex_destroy m2 failed"); return 1; } #endif } #ifndef NOT_CONSISTENT if (pthread_mutex_destroy (&m1) != 0) { puts ("mutex_destroy m1 failed"); return 1; } if (pthread_mutex_destroy (&m2) != 0) { puts ("mutex_destroy m2 failed"); return 1; } #endif if (pthread_mutexattr_destroy (&a) != 0) { puts ("mutexattr_destroy failed"); return 1; } return 0; }
int am_shm_lock(am_shm_t *am) { struct mem_pool *pool; int rv = AM_SUCCESS; /* once we enter the critical section, check if any other process hasn't * re-mapped our segment somewhere else (compare local_size to global_size which * will differ after successful am_shm_resize) */ #ifdef _WIN32 do { am->error = WaitForSingleObject(am->h[0], INFINITE); } while (am->error == WAIT_ABANDONED); if (am->local_size != *(am->global_size)) { if (UnmapViewOfFile(am->pool) == 0) { am->error = GetLastError(); return AM_EFAULT; } if (CloseHandle(am->h[2]) == 0) { am->error = GetLastError(); return AM_EFAULT; } am->h[2] = CreateFileMappingA(am->h[1], NULL, PAGE_READWRITE, 0, (DWORD) *(am->global_size), NULL); am->error = GetLastError(); if (am->h[2] == NULL) { return AM_EFAULT; } am->pool = (struct mem_pool *) MapViewOfFile(am->h[2], FILE_MAP_ALL_ACCESS, 0, 0, 0); am->error = GetLastError(); if (am->pool == NULL || (am->error != 0 && am->error != ERROR_ALREADY_EXISTS)) { return AM_EFAULT; } pool = (struct mem_pool *) am->pool; am->local_size = *(am->global_size); if (pool->user_offset > 0) { am->user = AM_GET_POINTER(pool, pool->user_offset); } } #else pthread_mutex_t *lock = (pthread_mutex_t *) am->lock; am->error = pthread_mutex_lock(lock); #if !defined(__APPLE__) && !defined(AIX) if (am->error == EOWNERDEAD) { am->error = pthread_mutex_consistent_np(lock); } #endif if (am->local_size != *(am->global_size)) { am->error = munmap(am->pool, am->local_size); if (am->error == -1) { am->error = errno; rv = AM_EFAULT; } am->pool = mmap(NULL, *(am->global_size), PROT_READ | PROT_WRITE, MAP_SHARED, am->fd, 0); if (am->pool == MAP_FAILED) { am->error = errno; rv = AM_EFAULT; } pool = (struct mem_pool *) am->pool; am->local_size = *(am->global_size); if (pool->user_offset > 0) { am->user = AM_GET_POINTER(pool, pool->user_offset); } } #endif return rv; }