diff options
author | cjihrig <cjihrig@gmail.com> | 2018-01-19 15:33:43 -0500 |
---|---|---|
committer | cjihrig <cjihrig@gmail.com> | 2018-01-23 20:34:39 -0500 |
commit | a083786c7733b5828102661a04a86884c934950a (patch) | |
tree | a45536a61b50e7b5fa68a77d6f594de730c4a346 /deps/uv/src/unix/os390-syscalls.c | |
parent | 63f78f5ddc8ac50ea19839827682c51ff3363ac2 (diff) | |
download | android-node-v8-a083786c7733b5828102661a04a86884c934950a.tar.gz android-node-v8-a083786c7733b5828102661a04a86884c934950a.tar.bz2 android-node-v8-a083786c7733b5828102661a04a86884c934950a.zip |
deps: upgrade libuv to 1.19.1
PR-URL: https://github.com/nodejs/node/pull/18260
Reviewed-By: James M Snell <jasnell@gmail.com>
Diffstat (limited to 'deps/uv/src/unix/os390-syscalls.c')
-rw-r--r-- | deps/uv/src/unix/os390-syscalls.c | 73 |
1 files changed, 67 insertions, 6 deletions
diff --git a/deps/uv/src/unix/os390-syscalls.c b/deps/uv/src/unix/os390-syscalls.c index 5bc489387e..21558ea868 100644 --- a/deps/uv/src/unix/os390-syscalls.c +++ b/deps/uv/src/unix/os390-syscalls.c @@ -25,6 +25,8 @@ #include <stdlib.h> #include <assert.h> #include <search.h> +#include <termios.h> +#include <sys/msg.h> #define CW_CONDVAR 32 @@ -103,10 +105,19 @@ static void maybe_resize(uv__os390_epoll* lst, unsigned int len) { unsigned int newsize; unsigned int i; struct pollfd* newlst; + struct pollfd event; if (len <= lst->size) return; + if (lst->size == 0) + event.fd = -1; + else { + /* Extract the message queue at the end. */ + event = lst->items[lst->size - 1]; + lst->items[lst->size - 1].fd = -1; + } + newsize = next_power_of_two(len); newlst = uv__realloc(lst->items, newsize * sizeof(lst->items[0])); @@ -115,11 +126,40 @@ static void maybe_resize(uv__os390_epoll* lst, unsigned int len) { for (i = lst->size; i < newsize; ++i) newlst[i].fd = -1; + /* Restore the message queue at the end */ + newlst[newsize - 1] = event; + lst->items = newlst; lst->size = newsize; } +static void init_message_queue(uv__os390_epoll* lst) { + struct { + long int header; + char body; + } msg; + + /* initialize message queue */ + lst->msg_queue = msgget(IPC_PRIVATE, 0622 | IPC_CREAT); + if (lst->msg_queue == -1) + abort(); + + /* + On z/OS, the message queue will be affiliated with the process only + when a send is performed on it. Once this is done, the system + can be queried for all message queues belonging to our process id. + */ + msg.header = 1; + if (msgsnd(lst->msg_queue, &msg, sizeof(msg.body), 0) != 0) + abort(); + + /* Clean up the dummy message sent above */ + if (msgrcv(lst->msg_queue, &msg, sizeof(msg.body), 0, 0) != sizeof(msg.body)) + abort(); +} + + static void before_fork(void) { uv_mutex_lock(&global_epoll_lock); } @@ -139,8 +179,13 @@ static void child_fork(void) { /* reset epoll list */ while (!QUEUE_EMPTY(&global_epoll_queue)) { + uv__os390_epoll* lst; q = QUEUE_HEAD(&global_epoll_queue); QUEUE_REMOVE(q); + lst = QUEUE_DATA(q, uv__os390_epoll, member); + uv__free(lst->items); + lst->items = NULL; + lst->size = 0; } uv_mutex_unlock(&global_epoll_lock); @@ -166,6 +211,10 @@ uv__os390_epoll* epoll_create1(int flags) { /* initialize list */ lst->size = 0; lst->items = NULL; + init_message_queue(lst); + maybe_resize(lst, 1); + lst->items[lst->size - 1].fd = lst->msg_queue; + lst->items[lst->size - 1].events = POLLIN; uv_once(&once, epoll_init); uv_mutex_lock(&global_epoll_lock); QUEUE_INSERT_TAIL(&global_epoll_queue, &lst->member); @@ -182,15 +231,20 @@ int epoll_ctl(uv__os390_epoll* lst, struct epoll_event *event) { uv_mutex_lock(&global_epoll_lock); - if(op == EPOLL_CTL_DEL) { + if (op == EPOLL_CTL_DEL) { if (fd >= lst->size || lst->items[fd].fd == -1) { uv_mutex_unlock(&global_epoll_lock); errno = ENOENT; return -1; } lst->items[fd].fd = -1; - } else if(op == EPOLL_CTL_ADD) { - maybe_resize(lst, fd + 1); + } else if (op == EPOLL_CTL_ADD) { + + /* Resizing to 'fd + 1' would expand the list to contain at least + * 'fd'. But we need to guarantee that the last index on the list + * is reserved for the message queue. So specify 'fd + 2' instead. + */ + maybe_resize(lst, fd + 2); if (lst->items[fd].fd != -1) { uv_mutex_unlock(&global_epoll_lock); errno = EEXIST; @@ -198,7 +252,7 @@ int epoll_ctl(uv__os390_epoll* lst, } lst->items[fd].fd = fd; lst->items[fd].events = event->events; - } else if(op == EPOLL_CTL_MOD) { + } else if (op == EPOLL_CTL_MOD) { if (fd >= lst->size || lst->items[fd].fd == -1) { uv_mutex_unlock(&global_epoll_lock); errno = ENOENT; @@ -215,17 +269,19 @@ int epoll_ctl(uv__os390_epoll* lst, int epoll_wait(uv__os390_epoll* lst, struct epoll_event* events, int maxevents, int timeout) { - size_t size; + nmsgsfds_t size; struct pollfd* pfds; int pollret; int reventcount; - size = lst->size; + size = _SET_FDS_MSGS(size, 1, lst->size - 1); pfds = lst->items; pollret = poll(pfds, size, timeout); if (pollret <= 0) return pollret; + pollret = _NFDS(pollret) + _NMSGS(pollret); + reventcount = 0; for (int i = 0; i < lst->size && i < maxevents && reventcount < pollret; ++i) { @@ -261,9 +317,14 @@ int epoll_file_close(int fd) { } void epoll_queue_close(uv__os390_epoll* lst) { + /* Remove epoll instance from global queue */ uv_mutex_lock(&global_epoll_lock); QUEUE_REMOVE(&lst->member); uv_mutex_unlock(&global_epoll_lock); + + /* Free resources */ + msgctl(lst->msg_queue, IPC_RMID, NULL); + lst->msg_queue = -1; uv__free(lst->items); lst->items = NULL; } |