⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pth_high.c

📁 Linux下的中文输入法
💻 C
📖 第 1 页 / 共 4 页
字号:
        /* if filedescriptor is still not readable,           let thread sleep until it is or the extra event occurs */        if (n == 0) {            ev = pth_event(PTH_EVENT_FD|PTH_UNTIL_FD_READABLE|PTH_MODE_STATIC, &ev_key, fd);            if (ev_extra != NULL)                pth_event_concat(ev, ev_extra, NULL);            n = pth_wait(ev);            if (ev_extra != NULL) {                pth_event_isolate(ev);                if (pth_event_status(ev) != PTH_STATUS_OCCURRED)                    return pth_error(-1, EINTR);            }        }    }    /* Now perform the actual read. We're now guarrantied to not block,       either because we were already in non-blocking mode or we determined       above by polling that the next read(2) call will not block.  But keep       in mind, that only 1 next read(2) call is guarrantied to not block       (except for the EINTR situation). */    while ((n = pth_sc(read)(fd, buf, nbytes)) < 0           && errno == EINTR) ;    pth_debug2("pth_read_ev: leave to thread \"%s\"", pth_current->name);    return n;}/* Pth variant of write(2) */ssize_t pth_write(int fd, const void *buf, size_t nbytes){    return pth_write_ev(fd, buf, nbytes, NULL);}/* Pth variant of write(2) with extra event(s) */ssize_t pth_write_ev(int fd, const void *buf, size_t nbytes, pth_event_t ev_extra){    struct timeval delay;    pth_event_t ev;    static pth_key_t ev_key = PTH_KEY_INIT;    fd_set fds;    int fdmode;    ssize_t rv;    ssize_t s;    int n;    pth_implicit_init();    pth_debug2("pth_write_ev: enter from thread \"%s\"", pth_current->name);    /* POSIX compliance */    if (nbytes == 0)        return 0;    if (!pth_util_fd_valid(fd))        return pth_error(-1, EBADF);    /* force filedescriptor into non-blocking mode */    if ((fdmode = pth_fdmode(fd, PTH_FDMODE_NONBLOCK)) == PTH_FDMODE_ERROR)        return pth_error(-1, EBADF);    /* poll filedescriptor if not already in non-blocking operation */    if (fdmode != PTH_FDMODE_NONBLOCK) {        /* now directly poll filedescriptor for writeability           to avoid unneccessary (and resource consuming because of context           switches, etc) event handling through the scheduler */        FD_ZERO(&fds);        FD_SET(fd, &fds);        delay.tv_sec  = 0;        delay.tv_usec = 0;        while ((n = pth_sc(select)(fd+1, NULL, &fds, NULL, &delay)) < 0               && errno == EINTR) ;        if (n < 0 && (errno == EINVAL || errno == EBADF))            return pth_error(-1, errno);        rv = 0;        for (;;) {            /* if filedescriptor is still not writeable,               let thread sleep until it is or event occurs */            if (n < 1) {                ev = pth_event(PTH_EVENT_FD|PTH_UNTIL_FD_WRITEABLE|PTH_MODE_STATIC, &ev_key, fd);                if (ev_extra != NULL)                    pth_event_concat(ev, ev_extra, NULL);                pth_wait(ev);                if (ev_extra != NULL) {                    pth_event_isolate(ev);                    if (pth_event_status(ev) != PTH_STATUS_OCCURRED) {                        pth_fdmode(fd, fdmode);                        return pth_error(-1, EINTR);                    }                }            }            /* now perform the actual write operation */            while ((s = pth_sc(write)(fd, buf, nbytes)) < 0                   && errno == EINTR) ;            if (s > 0)                rv += s;            /* although we're physically now in non-blocking mode,               iterate unless all data is written or an error occurs, because               we've to mimic the usual blocking I/O behaviour of write(2). */            if (s > 0 && s < (ssize_t)nbytes) {                nbytes -= s;                buf = (void *)((char *)buf + s);                n = 0;                continue;            }            /* pass error to caller, but not for partial writes (rv > 0) */            if (s < 0 && rv == 0)                rv = -1;            /* stop looping */            break;        }    }    else {        /* just perform the actual write operation */        while ((rv = pth_sc(write)(fd, buf, nbytes)) < 0               && errno == EINTR) ;    }    /* restore filedescriptor mode */    pth_shield { pth_fdmode(fd, fdmode); }    pth_debug2("pth_write_ev: leave to thread \"%s\"", pth_current->name);    return rv;}/* Pth variant of readv(2) */ssize_t pth_readv(int fd, const struct iovec *iov, int iovcnt){    return pth_readv_ev(fd, iov, iovcnt, NULL);}/* Pth variant of readv(2) with extra event(s) */ssize_t pth_readv_ev(int fd, const struct iovec *iov, int iovcnt, pth_event_t ev_extra){    struct timeval delay;    pth_event_t ev;    static pth_key_t ev_key = PTH_KEY_INIT;    fd_set fds;    int fdmode;    int n;    pth_implicit_init();    pth_debug2("pth_readv_ev: enter from thread \"%s\"", pth_current->name);    /* POSIX compliance */    if (iovcnt <= 0 || iovcnt > UIO_MAXIOV)        return pth_error(-1, EINVAL);    if (!pth_util_fd_valid(fd))        return pth_error(-1, EBADF);    /* check mode of filedescriptor */    if ((fdmode = pth_fdmode(fd, PTH_FDMODE_POLL)) == PTH_FDMODE_ERROR)        return pth_error(-1, EBADF);    /* poll filedescriptor if not already in non-blocking operation */    if (fdmode == PTH_FDMODE_BLOCK) {        /* first directly poll filedescriptor for readability           to avoid unneccessary (and resource consuming because of context           switches, etc) event handling through the scheduler */        FD_ZERO(&fds);        FD_SET(fd, &fds);        delay.tv_sec  = 0;        delay.tv_usec = 0;        while ((n = pth_sc(select)(fd+1, &fds, NULL, NULL, &delay)) < 0               && errno == EINTR) ;        /* if filedescriptor is still not readable,           let thread sleep until it is or event occurs */        if (n < 1) {            ev = pth_event(PTH_EVENT_FD|PTH_UNTIL_FD_READABLE|PTH_MODE_STATIC, &ev_key, fd);            if (ev_extra != NULL)                pth_event_concat(ev, ev_extra, NULL);            n = pth_wait(ev);            if (ev_extra != NULL) {                pth_event_isolate(ev);                if (pth_event_status(ev) != PTH_STATUS_OCCURRED)                    return pth_error(-1, EINTR);            }        }    }    /* Now perform the actual read. We're now guarrantied to not block,       either because we were already in non-blocking mode or we determined       above by polling that the next read(2) call will not block.  But keep       in mind, that only 1 next read(2) call is guarrantied to not block       (except for the EINTR situation). */#if PTH_FAKE_RWV    while ((n = pth_readv_faked(fd, iov, iovcnt)) < 0           && errno == EINTR) ;#else    while ((n = pth_sc(readv)(fd, iov, iovcnt)) < 0           && errno == EINTR) ;#endif    pth_debug2("pth_readv_ev: leave to thread \"%s\"", pth_current->name);    return n;}/* A faked version of readv(2) */intern ssize_t pth_readv_faked(int fd, const struct iovec *iov, int iovcnt){    char *buffer;    size_t bytes, copy, rv;    int i;    /* determine total number of bytes to read */    bytes = 0;    for (i = 0; i < iovcnt; i++) {        if (iov[i].iov_len <= 0)            return pth_error((ssize_t)(-1), EINVAL);        bytes += iov[i].iov_len;    }    if (bytes <= 0)        return pth_error((ssize_t)(-1), EINVAL);    /* allocate a temporary buffer */    if ((buffer = (char *)malloc(bytes)) == NULL)        return (ssize_t)(-1);    /* read data into temporary buffer (caller guarrantied us to not block) */    rv = pth_sc(read)(fd, buffer, bytes);    /* scatter read data into callers vector */    if (rv > 0) {        bytes = rv;        for (i = 0; i < iovcnt; i++) {            copy = pth_util_min(iov[i].iov_len, bytes);            memcpy(iov[i].iov_base, buffer, copy);            buffer += copy;            bytes  -= copy;            if (bytes <= 0)                break;        }    }    /* remove the temporary buffer */    pth_shield { free(buffer); }    /* return number of read bytes */    return(rv);}/* Pth variant of writev(2) */ssize_t pth_writev(int fd, const struct iovec *iov, int iovcnt){    return pth_writev_ev(fd, iov, iovcnt, NULL);}/* Pth variant of writev(2) with extra event(s) */ssize_t pth_writev_ev(int fd, const struct iovec *iov, int iovcnt, pth_event_t ev_extra){    struct timeval delay;    pth_event_t ev;    static pth_key_t ev_key = PTH_KEY_INIT;    fd_set fds;    int fdmode;    struct iovec *liov;    int liovcnt;    size_t nbytes;    ssize_t rv;    ssize_t s;    int n;    struct iovec tiov_stack[32];    struct iovec *tiov;    int tiovcnt;    pth_implicit_init();    pth_debug2("pth_writev_ev: enter from thread \"%s\"", pth_current->name);    /* POSIX compliance */    if (iovcnt <= 0 || iovcnt > UIO_MAXIOV)        return pth_error(-1, EINVAL);    if (!pth_util_fd_valid(fd))        return pth_error(-1, EBADF);    /* force filedescriptor into non-blocking mode */    if ((fdmode = pth_fdmode(fd, PTH_FDMODE_NONBLOCK)) == PTH_FDMODE_ERROR)        return pth_error(-1, EBADF);    /* poll filedescriptor if not already in non-blocking operation */    if (fdmode != PTH_FDMODE_NONBLOCK) {        /* provide temporary iovec structure */        if (iovcnt > sizeof(tiov_stack)) {            tiovcnt = (sizeof(struct iovec) * UIO_MAXIOV);            if ((tiov = (struct iovec *)malloc(tiovcnt)) == NULL)                return pth_error(-1, errno);        }        else {            tiovcnt = sizeof(tiov_stack);            tiov    = tiov_stack;        }        /* init return value and number of bytes to write */        rv      = 0;        nbytes  = pth_writev_iov_bytes(iov, iovcnt);        /* init local iovec structure */        liov    = NULL;        liovcnt = 0;        pth_writev_iov_advance(iov, iovcnt, 0, &liov, &liovcnt, tiov, tiovcnt);        /* first directly poll filedescriptor for writeability           to avoid unneccessary (and resource consuming because of context           switches, etc) event handling through the scheduler */        FD_ZERO(&fds);        FD_SET(fd, &fds);        delay.tv_sec  = 0;        delay.tv_usec = 0;        while ((n = pth_sc(select)(fd+1, NULL, &fds, NULL, &delay)) < 0               && errno == EINTR) ;        for (;;) {            /* if filedescriptor is still not writeable,               let thread sleep until it is or event occurs */            if (n < 1) {                ev = pth_event(PTH_EVENT_FD|PTH_UNTIL_FD_WRITEABLE|PTH_MODE_STATIC, &ev_key, fd);                if (ev_extra != NULL)                    pth_event_concat(ev, ev_extra, NULL);                pth_wait(ev);                if (ev_extra != NULL) {                    pth_event_isolate(ev);                    if (pth_event_status(ev) != PTH_STATUS_OCCURRED) {                        pth_fdmode(fd, fdmode);                        if (iovcnt > sizeof(tiov_stack))                            free(tiov);                        return pth_error(-1, EINTR);                    }                }            }            /* now perform the actual write operation */#if PTH_FAKE_RWV            while ((s = pth_writev_faked(fd, liov, liovcnt)) < 0                   && errno == EINTR) ;#else            while ((s = pth_sc(writev)(fd, liov, liovcnt)) < 0                   && errno == EINTR) ;#endif            if (s > 0)                rv += s;            /* although we're physically now in non-blocking mode,               iterate unless all data is written or an error occurs, because               we've to mimic the usual blocking I/O behaviour of writev(2) */            if (s > 0 && s < (ssize_t)nbytes) {                nbytes -= s;                pth_writev_iov_advance(iov, iovcnt, s, &liov, &liovcnt, tiov, tiovcnt);                n = 0;                continue;            }            /* pass error to caller, but not for partial writes (rv > 0) */            if (s < 0 && rv == 0)                rv = -1;            /* stop looping */            break;        }        /* cleanup */        if (iovcnt > sizeof(tiov_stack))            free(tiov);    }    else {        /* just perform the actual write operation */#if PTH_FAKE_RWV        while ((rv = pth_writev_faked(fd, iov, iovcnt)) < 0               && errno == EINTR) ;#else        while ((rv = pth_sc(writev)(fd, iov, iovcnt)) < 0

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -