/* {{{ set state bits on a thread, timeout where appropriate/required */ zend_bool pthreads_set_state_ex(PTHREAD thread, int mask, long timeout TSRMLS_DC) { zend_bool locked, dowait, result; if (mask & PTHREADS_ST_WAITING) { if (pthreads_state_lock(thread->state, &locked TSRMLS_CC)) { dowait = !pthreads_state_check(thread->state, PTHREADS_ST_JOINED TSRMLS_CC); if (dowait) pthreads_state_set_locked(thread->state, PTHREADS_ST_WAITING TSRMLS_CC); if (locked) pthreads_state_unlock(thread->state, locked TSRMLS_CC); if (dowait) { result = pthreads_synchro_wait_ex( thread->synchro, timeout TSRMLS_CC ); } else result = 0; } else result = 0; } else result = pthreads_state_set(thread->state, mask TSRMLS_CC); return result; } /* }}} */
/* {{{ set state bits on a thread, timeout where appropriate/required */ int pthreads_set_state_ex(PTHREAD thread, int mask, long timeout) { struct timeval now; struct timespec until; int wacquire = 0, timed = 0, result = -1; if (timeout>0L) { if (gettimeofday(&now, NULL)==SUCCESS) { long nsec = timeout * 1000; if (nsec > 1000000000L) { until.tv_sec = now.tv_sec + (nsec / 1000000000L); until.tv_nsec = (now.tv_usec * 1000) + (nsec % 1000000000L); } else { until.tv_sec = now.tv_sec; until.tv_nsec = (now.tv_usec * 1000) + timeout; } timed=1; } } pthreads_state_set(thread->state, mask); switch(mask){ case PTHREADS_ST_WAITING: { wacquire = PTHREADS_WLOCK(thread); if (wacquire == SUCCESS || wacquire == EDEADLK) { do { if (timed) { result=!pthread_cond_timedwait(thread->sync, thread->wait, &until); } else result=!pthread_cond_wait(thread->sync, thread->wait); } while(pthreads_state_isset(thread->state, PTHREADS_ST_WAITING)); if (wacquire != EDEADLK) PTHREADS_WUNLOCK(thread); } else zend_error(E_WARNING, "pthreads may have expereinced an internal error, I mean, really, who knows ?"); } break; case PTHREADS_ST_RUNNING: pthreads_globals_add(thread); break; } return result; } /* }}} */
/* {{{ set state bits on a thread, timeout where appropriate/required */ int pthreads_set_state_ex(PTHREAD thread, int mask, long timeout TSRMLS_DC) { int result = 0; if (mask & PTHREADS_ST_WAITING) { int slocked = pthreads_state_lock(thread->state TSRMLS_CC); int dowait = 0; if (slocked == SUCCESS ||slocked == EDEADLK) { dowait = !pthreads_state_check(thread->state, PTHREADS_ST_JOINED TSRMLS_CC); if (dowait) pthreads_state_set_locked(thread->state, PTHREADS_ST_WAITING TSRMLS_CC); if (slocked != EDEADLK) pthreads_state_unlock(thread->state TSRMLS_CC); if (dowait) { result = pthreads_synchro_wait_ex( thread->synchro, timeout TSRMLS_CC ); } else result = 0; } else result = 0; } else result = pthreads_state_set(thread->state, mask TSRMLS_CC); return result; } /* }}} */