summaryrefslogtreecommitdiffstats
path: root/winsup/cygserver/sysv_sem.cc
diff options
context:
space:
mode:
Diffstat (limited to 'winsup/cygserver/sysv_sem.cc')
-rw-r--r--winsup/cygserver/sysv_sem.cc92
1 files changed, 56 insertions, 36 deletions
diff --git a/winsup/cygserver/sysv_sem.cc b/winsup/cygserver/sysv_sem.cc
index bcd0dc251..477df4a26 100644
--- a/winsup/cygserver/sysv_sem.cc
+++ b/winsup/cygserver/sysv_sem.cc
@@ -35,6 +35,7 @@ __FBSDID("$FreeBSD: /repoman/r/ncvs/src/sys/kern/sysv_sem.c,v 1.70 2004/05/30 20
#include "cygserver.h"
#include "process.h"
#include "cygserver_ipc.h"
+#include <sys/smallprint.h>
#ifdef __CYGWIN__
#define __semctl semctl
@@ -53,7 +54,7 @@ static int semvalid(int semid, struct semid_ds *semaptr);
static struct sem_undo *semu_alloc(struct thread *td);
static int semundo_adjust(struct thread *td, struct sem_undo **supptr,
int semid, int semnum, int adjval);
-static void semundo_clear(int semid, int semnum);
+static void semundo_clear(int semid, int semnum, struct thread *td);
#ifndef _SYS_SYSPROTO_H_
struct __semctl_args;
@@ -88,7 +89,7 @@ static eventhandler_tag semexit_tag;
#define SEMUNDO_LOCK() mtx_lock(&SEMUNDO_MTX);
#define SEMUNDO_HOOKLOCK() _mtx_lock(&SEMUNDO_MTX, p->winpid, __FILE__, __LINE__);
#define SEMUNDO_UNLOCK() mtx_unlock(&SEMUNDO_MTX);
-#define SEMUNDO_LOCKASSERT(how) mtx_assert(&SEMUNDO_MTX, (how));
+#define SEMUNDO_LOCKASSERT(how,pid) mtx_assert(&SEMUNDO_MTX, (how), (pid));
struct sem {
u_short semval; /* semaphore value */
@@ -108,7 +109,11 @@ struct undo {
struct sem_undo {
SLIST_ENTRY(sem_undo) un_next; /* ptr to next active undo structure */
+#ifdef __CYGWIN__
+ DWORD un_proc; /* owner of this structure */
+#else
struct proc *un_proc; /* owner of this structure */
+#endif
short un_cnt; /* # of active entries */
struct undo un_ent[1]; /* undo entries */
};
@@ -240,10 +245,18 @@ seminit(void)
sema[i].sem_perm.seq = 0;
}
for (i = 0; i < seminfo.semmni; i++)
- mtx_init(&sema_mtx[i], "semid", NULL, MTX_DEF);
+ {
+ char *buf = (char *)malloc (16);
+ __small_sprintf (buf, "semid[%d]", i);
+ mtx_init(&sema_mtx[i], buf, NULL, MTX_DEF);
+ }
for (i = 0; i < seminfo.semmnu; i++) {
struct sem_undo *suptr = SEMU(i);
+#ifdef __CYGWIN__
+ suptr->un_proc = 0;
+#else
suptr->un_proc = NULL;
+#endif
}
SLIST_INIT(&semu_list);
mtx_init(&sem_mtx, "sem", NULL, MTX_DEF);
@@ -351,7 +364,7 @@ semu_alloc(struct thread *td)
struct sem_undo **supptr;
int attempt;
- SEMUNDO_LOCKASSERT(MA_OWNED);
+ SEMUNDO_LOCKASSERT(MA_OWNED, td->td_proc->winpid);
/*
* Try twice to allocate something.
* (we'll purge an empty structure after the first pass so
@@ -366,10 +379,14 @@ semu_alloc(struct thread *td)
for (i = 0; i < seminfo.semmnu; i++) {
suptr = SEMU(i);
+#ifdef __CYGWIN__
+ if (suptr->un_proc == 0) {
+#else
if (suptr->un_proc == NULL) {
+#endif
SLIST_INSERT_HEAD(&semu_list, suptr, un_next);
suptr->un_cnt = 0;
- suptr->un_proc = td->td_proc;
+ suptr->un_proc = td->td_proc->winpid;
return(suptr);
}
}
@@ -386,7 +403,11 @@ semu_alloc(struct thread *td)
SLIST_FOREACH_PREVPTR(suptr, supptr, &semu_list,
un_next) {
if (suptr->un_cnt == 0) {
+#ifdef __CYGWIN__
+ suptr->un_proc = 0;
+#else
suptr->un_proc = NULL;
+#endif
did_something = 1;
*supptr = SLIST_NEXT(suptr, un_next);
break;
@@ -421,7 +442,7 @@ semundo_adjust(struct thread *td, struct sem_undo **supptr, int semid,
struct undo *sunptr;
int i;
- SEMUNDO_LOCKASSERT(MA_OWNED);
+ SEMUNDO_LOCKASSERT(MA_OWNED, td->td_proc->winpid);
/* Look for and remember the sem_undo if the caller doesn't provide
it */
@@ -429,7 +450,7 @@ semundo_adjust(struct thread *td, struct sem_undo **supptr, int semid,
if (suptr == NULL) {
SLIST_FOREACH(suptr, &semu_list, un_next) {
#ifdef __CYGWIN__
- if (suptr->un_proc->cygpid == p->cygpid) {
+ if (suptr->un_proc == p->winpid) {
#else
if (suptr->un_proc == p) {
#endif
@@ -486,11 +507,11 @@ semundo_adjust(struct thread *td, struct sem_undo **supptr, int semid,
}
static void
-semundo_clear(int semid, int semnum)
+semundo_clear(int semid, int semnum, struct thread *td)
{
struct sem_undo *suptr;
- SEMUNDO_LOCKASSERT(MA_OWNED);
+ SEMUNDO_LOCKASSERT(MA_OWNED, td->td_proc->winpid);
SLIST_FOREACH(suptr, &semu_list, un_next) {
struct undo *sunptr = &suptr->un_ent[0];
int i = 0;
@@ -647,7 +668,7 @@ __semctl(struct thread *td, struct __semctl_args *uap)
}
semaptr->sem_perm.mode = 0;
SEMUNDO_LOCK();
- semundo_clear(semid, -1);
+ semundo_clear(semid, -1, td);
SEMUNDO_UNLOCK();
wakeup(semaptr);
break;
@@ -770,7 +791,7 @@ __semctl(struct thread *td, struct __semctl_args *uap)
}
semaptr->sem_base[semnum].semval = real_arg.val;
SEMUNDO_LOCK();
- semundo_clear(semid, semnum);
+ semundo_clear(semid, semnum, td);
SEMUNDO_UNLOCK();
wakeup(semaptr);
break;
@@ -808,7 +829,7 @@ raced:
semaptr->sem_base[i].semval = usval;
}
SEMUNDO_LOCK();
- semundo_clear(semid, -1);
+ semundo_clear(semid, -1, td);
SEMUNDO_UNLOCK();
wakeup(semaptr);
break;
@@ -821,7 +842,7 @@ raced:
if (error == 0)
td->td_retval[0] = rval;
done2:
- if (mtx_owned(sema_mtxp))
+ if (mtx_owned(sema_mtxp, td->td_proc->winpid))
mtx_unlock(sema_mtxp);
if (array != NULL)
sys_free(array, M_TEMP);
@@ -850,7 +871,7 @@ semget(struct thread *td, struct semget_args *uap)
struct ucred *cred = td->td_ucred;
#endif
- DPRINTF(("semget(0x%x, %d, 0%o)\n", key, nsems, semflg));
+ DPRINTF(("semget(0x%X, %d, 0%o)\n", key, nsems, semflg));
if (!jail_sysvipc_allowed && jailed(td->td_ucred))
return (ENOSYS);
@@ -1056,7 +1077,7 @@ semop(struct thread *td, struct semop_args *uap)
semptr = &semaptr->sem_base[sopptr->sem_num];
DPRINTF((
- "semop: semaptr=%x, sem_base=%x, "
+ "semop: semaptr=%x, sem_base=%x, "
"semptr=%x, sem[%d]=%d : op=%d, flag=%s\n",
semaptr, semaptr->sem_base, semptr,
sopptr->sem_num, semptr->semval, sopptr->sem_op,
@@ -1252,18 +1273,6 @@ semexit_myhook(void *arg, struct proc *p)
struct sem_undo *suptr;
struct sem_undo **supptr;
-#ifdef __CYGWIN__
- /*
- * Search all mutexes, if some of them are still owned by the
- * leaving process. If so, unlock them.
- */
- if (sem_mtx.owner == p->winpid)
- mtx_unlock(&sem_mtx);
- for (int i = 0; i < seminfo.semmni; i++)
- if (sema_mtx[i].owner == p->winpid)
- mtx_unlock(&sema_mtx[i]);
-#endif /* __CYGWIN__ */
-
/*
* Go through the chain of undo vectors looking for one
* associated with this process.
@@ -1271,16 +1280,20 @@ semexit_myhook(void *arg, struct proc *p)
SEMUNDO_HOOKLOCK();
SLIST_FOREACH_PREVPTR(suptr, supptr, &semu_list, un_next) {
#ifdef __CYGWIN__
- if (suptr->un_proc->cygpid == p->cygpid)
+ if (suptr->un_proc == p->winpid)
#else
if (suptr->un_proc == p)
#endif
break;
}
+#ifndef __CYGWIN__
SEMUNDO_UNLOCK();
+#endif
- if (suptr == NULL)
+ if (suptr == NULL) {
+ SEMUNDO_UNLOCK();
return;
+ }
#ifdef __CYGWIN__
DPRINTF(("proc @%u(%u) has undo structure with %d entries\n",
@@ -1309,8 +1322,8 @@ semexit_myhook(void *arg, struct proc *p)
_mtx_lock(sema_mtxp, p->winpid, __FILE__, __LINE__);
#else
mtx_lock(sema_mtxp);
-#endif
SEMUNDO_HOOKLOCK();
+#endif
if ((semaptr->sem_perm.mode & SEM_ALLOC) == 0)
panic("semexit - semid not allocated");
if (semnum >= semaptr->sem_nsems)
@@ -1318,13 +1331,11 @@ semexit_myhook(void *arg, struct proc *p)
DPRINTF((
#ifdef __CYGWIN__
- "semexit: %u(%u) id=%d num=%d(adj=%d) ; sem=%d\n",
- suptr->un_proc->cygpid, suptr->un_proc->winpid,
- suptr->un_ent[ix].un_id,
+ "semexit: %u id=%d num=%d(adj=%d) ; sem=%d\n",
#else
"semexit: %08x id=%d num=%d(adj=%d) ; sem=%d\n",
- suptr->un_proc, suptr->un_ent[ix].un_id,
#endif
+ suptr->un_proc, suptr->un_ent[ix].un_id,
suptr->un_ent[ix].un_num,
suptr->un_ent[ix].un_adjval,
semaptr->sem_base[semnum].semval));
@@ -1340,17 +1351,26 @@ semexit_myhook(void *arg, struct proc *p)
wakeup(semaptr);
DPRINTF(("semexit: back from wakeup\n"));
- mtx_unlock(sema_mtxp);
+ _mtx_unlock(sema_mtxp, __FILE__, __LINE__);
+#ifndef __CYGWIN__
SEMUNDO_UNLOCK();
+#endif
}
}
/*
* Deallocate the undo vector.
*/
- DPRINTF(("removing vector\n"));
+ DPRINTF(("removing vector (%u)\n", suptr->un_proc));
+#ifdef __CYGWIN__
+ suptr->un_proc = 0;
+#else
suptr->un_proc = NULL;
+#endif
*supptr = SLIST_NEXT(suptr, un_next);
+#ifdef __CYGWIN__
+ SEMUNDO_UNLOCK();
+#endif
}
#ifndef __CYGWIN__