📄 nb.c
字号:
bits++; tocount &= tocount - 1; } return (bits);}static struct timeval SelPol = {0, 0};/* * See if IO is immediately ready on a set of descriptors. * Be careful to not have side effects on descriptors since * the intent is to block until something really happens. * True polled select does have the side effect on descriptors, * and is handled in select itself. */static intpoll_select(width, rmask, wmask, emask) int width; fd_set *rmask, *wmask, *emask;{ fd_set c_rmask, c_wmask, c_emask; int nready = 0; set_masks(rmask, wmask, emask, &c_rmask, &c_wmask, &c_emask); do { timerclear(&SelPol); nready = syscall(SYS_select, width, rmask, wmask, emask, &SelPol); } while ((nready == -1) && (errno == EINTR)); if (nready <= 0) set_masks(&c_rmask, &c_wmask, &c_emask, rmask, wmask, emask); return (nready);}/* * Wait until IO may be available on a set of descriptors. */static intblock_until_notified(width, rmask, wmask, emask, timeout) fd_set *rmask, *wmask, *emask; int width; struct timeval *timeout;{ fd_set c_rmask, c_wmask, c_emask; thread_t aid; fd_set ret_mask; fd_set req_mask; fd_set countmask; int err; get_agent(&aid, AGT_SIGIO); set_masks(rmask, wmask, emask, &c_rmask, &c_wmask, &c_emask); or_masks(&req_mask, &c_rmask, &c_wmask, &c_emask);again: if (!(poll_select(width, &c_rmask, &c_wmask, &c_emask))) { err = msg_recv(&aid, (caddr_t *)0, (int *)0, (caddr_t *)0, (int *)0, timeout); if ((err == -1) && (lwp_geterr() == LE_TIMEOUT)) { return (0); } msg_reply(aid); } or_masks(&ret_mask, &c_rmask, &c_wmask, &c_emask); if (!mask_match(&ret_mask, &req_mask)) { set_masks(rmask, wmask, emask, &c_rmask, &c_wmask, &c_emask); goto again; } set_masks(&c_rmask, &c_wmask, &c_emask, rmask, wmask, emask); or_masks(&countmask, emask, rmask, wmask); return (countbits(&countmask, width));}/* * ----------------------------------------------------------------------- * SYSTEM CALLS * ----------------------------------------------------------------------- */intsocket(af, type, protocol) int af; int type; int protocol;{ int s; INIT(); s = syscall(SYS_socket, af, type, protocol); if (s == -1) return (-1); if (nblk_io(s, TRUE) == -1) return (-1); return (s);}intaccept(s, addr, addrlen) int s; struct sockaddr *addr; int *addrlen;{ register int ns; register int saved_len = *addrlen; INIT(); if (nblk_io(s, TRUE) == -1) return (-1); ns = syscall(SYS_accept, s, addr, addrlen); while ((ns == -1) && ((errno == EWOULDBLOCK) || (errno == EINTR))) { *addrlen = saved_len; block_io(s, READ); ns = syscall(SYS_accept, s, addr, addrlen); } return (ns);}intconnect(s, name, namelen) int s; struct sockaddr *name; int namelen;{ register int err; INIT(); if (nblk_io(s, TRUE) == -1) return (-1); err = syscall(SYS_connect, s, name, namelen); while ((err == -1) && ((errno == EINPROGRESS) || (errno == EWOULDBLOCK) || (errno == EINTR))) { block_io(s, WRITE); err = syscall(SYS_connect, s, name, namelen); } if ((err == -1) && (errno == EISCONN)) err = 0; return (err);}intpipe(fds) int fds[];{ INIT(); if (mpipe(fds) == -1) return (-1); if (nblk_io(fds[0], TRUE) == -1) return (-1); if (nblk_io(fds[1], TRUE) == -1) return (-1); return (0);}intopen(path, flags, mode) char *path; int flags; int mode;{ register int fd; INIT(); fd = syscall(SYS_open, path, flags, mode); if (fd == -1) return (-1); if (nblk_io(fd, FALSE) == -1) return (-1); return (fd);}intclose(fd){ INIT(); if (fcntl(fd, F_SETFL, NbDesc[fd].old_flag) == -1) { return (-1); } if (syscall(SYS_close, fd) == -1) return (-1); NbDesc[fd].issocket = FALSE; NbSet[fd] = FALSE; return (0);}intwrite(fd, buf, nbytes) int fd; caddr_t buf; int nbytes;{ register int nwrote; register caddr_t next = buf; register int total_written = 0; register int l_nbytes = nbytes; INIT(); if (nblk_io(fd, FALSE) == -1) return (-1); do { nwrote = syscall(SYS_write, fd, next, l_nbytes); while ((nwrote == -1) && ((errno == EWOULDBLOCK) || (errno == EINTR))) { block_io(fd, WRITE); nwrote = syscall(SYS_write, fd, next, l_nbytes); } if (nwrote == -1) break; else { total_written += nwrote; if (total_written < nbytes) next += (l_nbytes = (nbytes - total_written)); } } while (total_written < nbytes); if (nwrote == -1) return (-1); return (total_written);}intread(fd, buf, nbytes) int fd; char *buf; int nbytes;{ register int nread; INIT(); if (nblk_io(fd, FALSE) == -1) return (-1); nread = syscall(SYS_read, fd, buf, nbytes); while ((nread == -1) && ((errno == EWOULDBLOCK) || (errno == EINTR))) { block_io(fd, READ); nread = syscall(SYS_read, fd, buf, nbytes); } return (nread);}intselect(width, rmask, wmask, emask, timeout) int width; fd_set *rmask; fd_set *wmask; fd_set *emask; struct timeval *timeout;{ register int err; register int nready; register int i; fd_set mask; /* composite mask of fds to be marked ASYNC */ INIT(); or_masks(&mask, rmask, wmask, emask); if ((timeout != NULL) && (timeout->tv_sec == 0) && (timeout->tv_usec == 0)) { err = syscall(SYS_select, width, rmask, wmask, emask, timeout); return (err); } for (i = 0; i < NOFILE; i++) { if (FD_ISSET(i, &mask)) { if (nblk_io(i, FALSE) == -1) { return (-1); } } } nready = block_until_notified(width, rmask, wmask, emask, timeout); return (nready);}intsend(s, msg, len, flags) int s; char *msg; int len; int flags;{ register int nsent; INIT(); if (nblk_io(s, TRUE) == -1) return (-1); nsent = syscall(SYS_send, s, msg, len, flags); while ((nsent == -1) && ((errno == EWOULDBLOCK) || (errno == EINTR))) { block_io(s, WRITE); nsent = syscall(SYS_send, s, msg, len, flags); } return (nsent);}intsendto(s, msg, len, flags, to, tolen) int s; char *msg; int len; int flags; struct sockaddr *to; int tolen;{ register int nsent; INIT(); if (nblk_io(s, TRUE) == -1) return (-1); nsent = syscall(SYS_sendto, s, msg, len, flags, to, tolen); while ((nsent == -1) && ((errno == EWOULDBLOCK) || (errno == EINTR))) { block_io(s, WRITE); nsent = syscall(SYS_sendto, s, msg, len, flags, to, tolen); } return (nsent);}intsendmsg(s, msg, flags) int s; struct msghdr msg[]; int flags;{ register int nsent; INIT(); if (nblk_io(s, TRUE) == -1) return (-1); nsent = syscall(SYS_sendmsg, s, msg, flags); while ((nsent == -1) && ((errno == EWOULDBLOCK) || (errno == EINTR))) { block_io(s, WRITE); nsent = syscall(SYS_sendmsg, s, msg, flags); } return (nsent);}intrecvfrom(s, buf, len, flags, from, fromlen) int s; char *buf; int len; int flags; struct sockaddr *from; int *fromlen;{ register int nrecvd; register int saved_len = *fromlen; /* if nrecvd=-1; reset fromlen */ INIT(); if (nblk_io(s, TRUE) == -1) return (-1); nrecvd = syscall(SYS_recvfrom, s, buf, len, flags, from, fromlen); while ((nrecvd == -1) && ((errno == EWOULDBLOCK) || (errno == EINTR))){ block_io(s, READ); *fromlen = saved_len; nrecvd = syscall(SYS_recvfrom, s, buf, len, flags, from, fromlen); } return (nrecvd);}intrecvmsg(s, msg, flags) int s; struct msghdr msg[]; int flags;{ register int nrecvd; INIT(); if (nblk_io(s, TRUE) == -1) return (-1); nrecvd = syscall(SYS_recvmsg, s, msg, flags); while ((nrecvd == -1) && ((errno == EWOULDBLOCK) || (errno == EINTR))) { block_io(s, READ); nrecvd = syscall(SYS_recvmsg, s, msg, flags); } return (nrecvd);}/* * Should have only a single thread gathering the hwp's * since each thread using a wait agent will see signals for ALL hwp's. * Could do IO like this too: each read (say) registers with a SIGIO agent * thread that wakes up the registerer only when HIS IO is ready. * SIGIO has this same property of being able to report 1 signal for multiple * IO however so this method could deadlock. * This is a general problem sith signals: ons signal for many events is * possible. With real lwps, if you want to be non-blocking, * you simply *block* on the thing you want: wait(pid). This doesn't * affect the rest of the pod. Hwps aren't an answer here because * you don't want to fork a hwp to wait for a hwp. lwp's give you * the semantics of sharing descriptors that hwp's don't. * In addition to performance, this is a big difference. */pid_twait(status) union wait *status;{ thread_t aid; int chld_pid; int err; sigchldev_t *agtinfo; struct rusage rusage; INIT(); chld_pid = wait3(status, WNOHANG|WUNTRACED, &rusage); if (chld_pid < 0) { /* no children */ return (-1); } if (chld_pid > 0) { /* reaped a child right away */ return (chld_pid); } /* Have children, but none have exited yet */ get_agent(&aid, AGT_SIGCHLD); err = msg_recv(&aid, (caddr_t *)&agtinfo, (int *)0, (caddr_t *)0, (int *)0, INFINITY); if (err == -1) { return (-1); } chld_pid = agtinfo->sigchld_pid; *status = agtinfo->sigchld_status; msg_reply(aid); return (chld_pid);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -