X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=ipc%2Fsem.c;h=416d06aff20e4db0bab8f3a4df642e6d4b9510e3;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=b1bd0af6727c0585a3419887fd7e745b43649277;hpb=c7b5ebbddf7bcd3651947760f423e3783bbe6573;p=linux-2.6.git diff --git a/ipc/sem.c b/ipc/sem.c index b1bd0af67..416d06aff 100644 --- a/ipc/sem.c +++ b/ipc/sem.c @@ -71,8 +71,7 @@ #include #include #include -#include - +#include #include #include "util.h" @@ -177,7 +176,7 @@ static int newary (key_t key, int nsems, int semflg) sma->sem_perm.mode = (semflg & S_IRWXUGO); sma->sem_perm.key = key; - sma->sem_perm.xid = current->xid; + sma->sem_perm.xid = vx_current_xid(); sma->sem_perm.security = NULL; retval = security_sem_alloc(sma); @@ -360,8 +359,22 @@ static void update_queue (struct sem_array * sma) if (error <= 0) { struct sem_queue *n; remove_from_queue(sma,q); - n = q->next; q->status = IN_WAKEUP; + /* + * Continue scanning. The next operation + * that must be checked depends on the type of the + * completed operation: + * - if the operation modified the array, then + * restart from the head of the queue and + * check for threads that might be waiting + * for semaphore values to become 0. + * - if the operation didn't modify the array, + * then just continue. + */ + if (q->alter) + n = sma->sem_pending; + else + n = q->next; wake_up_process(q->sleeper); /* hands-off: q will disappear immediately after * writing q->status. @@ -526,7 +539,7 @@ static int semctl_nolock(int semid, int semnum, int cmd, int version, union semu struct semid64_ds tbuf; int id; - if(semid >= sem_ids.size) + if(semid >= sem_ids.entries->size) return -EINVAL; memset(&tbuf,0,sizeof(tbuf)); @@ -1121,8 +1134,11 @@ retry_undos: goto out_unlock_free; error = try_atomic_semop (sma, sops, nsops, un, current->tgid); - if (error <= 0) - goto update; + if (error <= 0) { + if (alter && error == 0) + update_queue (sma); + goto out_unlock_free; + } /* We need to sleep on this operation, so we put the current * task into the pending queue and go to sleep. @@ -1134,6 +1150,7 @@ retry_undos: queue.undo = un; queue.pid = current->tgid; queue.id = semid; + queue.alter = alter; if (alter) append_to_queue(sma ,&queue); else @@ -1185,9 +1202,6 @@ retry_undos: remove_from_queue(sma,&queue); goto out_unlock_free; -update: - if (alter) - update_queue (sma); out_unlock_free: sem_unlock(sma); out_free: