diff options
author | jhb <jhb@FreeBSD.org> | 2001-01-23 21:06:30 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2001-01-23 21:06:30 +0000 |
commit | c318d324943d5dc1bdf65fdac1348136715c8638 (patch) | |
tree | a6e0944214f6184d238c95209d92266936f16827 /sys/dev/streams | |
parent | 9d20e25a89c745d775d33b8005a6ca26d97faa5a (diff) | |
download | FreeBSD-src-c318d324943d5dc1bdf65fdac1348136715c8638.zip FreeBSD-src-c318d324943d5dc1bdf65fdac1348136715c8638.tar.gz |
- Add necessary proc locking.
- Use proper atomic operations to make the run time initialization
controlled by svr_str_initialized be MP safe.
- Use appropriate queue(3) macros where needed.
Diffstat (limited to 'sys/dev/streams')
-rw-r--r-- | sys/dev/streams/streams.c | 20 |
1 files changed, 15 insertions, 5 deletions
diff --git a/sys/dev/streams/streams.c b/sys/dev/streams/streams.c index b7da7ee..1d779f4 100644 --- a/sys/dev/streams/streams.c +++ b/sys/dev/streams/streams.c @@ -207,8 +207,12 @@ streamsopen(dev_t dev, int oflags, int devtype, struct proc *p) int error; int family; - if (p->p_dupfd >= 0) + PROC_LOCK(p); + if (p->p_dupfd >= 0) { + PROC_UNLOCK(p); return ENODEV; + } + PROC_UNLOCK(p); switch (minor(dev)) { case dev_udp: @@ -271,7 +275,9 @@ streamsopen(dev_t dev, int oflags, int devtype, struct proc *p) fp->f_type = DTYPE_SOCKET; (void)svr4_stream_get(fp); + PROC_LOCK(p); p->p_dupfd = fd; + PROC_UNLOCK(p); return ENXIO; } @@ -318,7 +324,9 @@ svr4_ptm_alloc(p) case ENXIO: return error; case 0: + PROC_LOCK(p); p->p_dupfd = p->p_retval[0]; + PROC_UNLOCK(p); return ENXIO; default: if (ttynumbers[++n] == '\0') { @@ -367,13 +375,15 @@ svr4_delete_socket(p, fp) struct svr4_sockcache_entry *e; void *cookie = ((struct socket *) fp->f_data)->so_emuldata; - if (!svr4_str_initialized) { - TAILQ_INIT(&svr4_head); - svr4_str_initialized = 1; + while (svr4_str_initialized != 2) { + if (atomic_cmpset_acq_int(&svr4_str_initialized, 0, 1)) { + TAILQ_INIT(&svr4_head); + atomic_store_rel_int(&svr4_str_initialized, 2); + } return; } - for (e = svr4_head.tqh_first; e != NULL; e = e->entries.tqe_next) + TAILQ_FOREACH(e, &svr4_head, entries) if (e->p == p && e->cookie == cookie) { TAILQ_REMOVE(&svr4_head, e, entries); DPRINTF(("svr4_delete_socket: %s [%p,%d,%d]\n", |