Hi, I just ran into a situtation where I didn't want sem_acquire() to block forever if the semaphore was already locked, but instead just return an error condition. There didn't seem to be a way to do this in current PHP API, so I wrote a patch for it. I tried to write it in such a way that current scripts that use sem_acquire() would not break. The new sem_acquire signature is: int sem_acquire (int sem_identifier [, int nowait]) If the nowait flag is specified, sem_acquire() will return false immediately if it is unable to acquire the semaphore without blocking. When sem_acquire() returns false, the nowait flag will be true if the semaphore could not be acquired without blocking. The nowait flag will be false if a "normal" sem_acquire() error occurred. If sem_acquire() returns true, the value of nowait should be ignored. The input value of nowait is ignored, and must be specified as a reference. If the nowait flag is not specified, the behaviour of sem_acquire is identical to the current PHP behaviour. PHP code sample ------------------------ $nowait = 0; /* initialize the variable */ $id = sem_get(0xF00); sem_acquire($id); /* lock */ /* lock again */ if (!sem_acquire($id, &$nowait)) { if ($nowait) { echo "Already locked."; } else { die("sem_acquire error occurred"); } } /* release the id */ sem_release($id); ------------------------ Below is the patch against PHP 4.0.4pl1. Cheers, Michael --- php-4.0.4pl1.orig/ext/sysvsem/sysvsem.c Wed Oct 25 13:44:01 2000 +++ php-4.0.4pl1/ext/sysvsem/sysvsem.c Mon Jan 22 11:37:12 2001 @@ -283,8 +283,8 @@ static void php_sysvsem_semop(INTERNAL_FUNCTION_PARAMETERS, int acquire) { - pval **arg_id; - int id, type; + pval **arg_id, **arg_nowait; + int id, type, nowait; sysvsem_sem *sem_ptr; struct sembuf sop; @@ -295,7 +295,31 @@ } convert_to_long_ex(arg_id); id = (int)(*arg_id)->value.lval; + nowait = 0; break; + + case 2: + /* nowait flag is only allowed for sem_acquire */ + if (!acquire) { + WRONG_PARAM_COUNT; + } + if (zend_get_parameters_ex(2, &arg_id, &arg_nowait)==FAILURE) { + RETURN_FALSE; + } + + if (!ParameterPassedByReference(ht, 2)) { + php_error(E_WARNING, "nowait flag must be passed by +reference."); + RETURN_FALSE; + } + + convert_to_long_ex(arg_id); + convert_to_boolean_ex(arg_nowait); + + id = (int)(*arg_id)->value.lval; + nowait = 1; + (int)(*arg_nowait)->value.lval = 0; + break; + default: WRONG_PARAM_COUNT; break; @@ -315,13 +339,25 @@ sop.sem_num = SYSVSEM_SEM; sop.sem_op = acquire ? -1 : 1; sop.sem_flg = SEM_UNDO; + if (nowait) { + sop.sem_flg |= IPC_NOWAIT; + } while (semop(sem_ptr->semid, &sop, 1) == -1) { - if (errno != EINTR) { - php_error(E_WARNING, "semop(%s) failed for key 0x%x: %s", - acquire ? "acquire" : "release", sem_ptr->key, strerror(errno)); - RETURN_FALSE; - } + switch (errno) { + case EINTR: + break; + case EAGAIN: + if (nowait) { + (int)(*arg_nowait)->value.lval = 1; /* set nowait flag */ + RETURN_FALSE; + } + /* fall through */ + default: + php_error(E_WARNING, "semop(%s) failed for key 0x%x: %s", + acquire ? "acquire" : "release", sem_ptr->key, +strerror(errno)); + RETURN_FALSE; + } } sem_ptr->count -= acquire ? -1 : 1; -- Michael Vines Black Echo Systems Inc. [EMAIL PROTECTED] -- PHP Development Mailing List <http://www.php.net/> To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] To contact the list administrators, e-mail: [EMAIL PROTECTED]