summaryrefslogtreecommitdiff
path: root/deps/uv/src/unix/os390-syscalls.c
diff options
context:
space:
mode:
authorcjihrig <cjihrig@gmail.com>2018-01-19 15:33:43 -0500
committercjihrig <cjihrig@gmail.com>2018-01-23 20:34:39 -0500
commita083786c7733b5828102661a04a86884c934950a (patch)
treea45536a61b50e7b5fa68a77d6f594de730c4a346 /deps/uv/src/unix/os390-syscalls.c
parent63f78f5ddc8ac50ea19839827682c51ff3363ac2 (diff)
downloadandroid-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.c73
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;
}