bf0448b519080e744de65b12e388e79643cc7521
[platform/upstream/cmake.git] / Utilities / cmlibuv / src / unix / os390.c
1 /* Copyright libuv project contributors. All rights reserved.
2  *
3  * Permission is hereby granted, free of charge, to any person obtaining a copy
4  * of this software and associated documentation files (the "Software"), to
5  * deal in the Software without restriction, including without limitation the
6  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7  * sell copies of the Software, and to permit persons to whom the Software is
8  * furnished to do so, subject to the following conditions:
9  *
10  * The above copyright notice and this permission notice shall be included in
11  * all copies or substantial portions of the Software.
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19  * IN THE SOFTWARE.
20  */
21
22 #include "internal.h"
23 #include <sys/ioctl.h>
24 #include <net/if.h>
25 #include <utmpx.h>
26 #include <unistd.h>
27 #include <sys/ps.h>
28 #include <builtins.h>
29 #include <termios.h>
30 #include <sys/msg.h>
31 #include <sys/resource.h>
32 #include "zos-base.h"
33 #if defined(__clang__)
34 #include "csrsic.h"
35 #else
36 #include "//'SYS1.SAMPLIB(CSRSIC)'"
37 #endif
38
39 #define CVT_PTR           0x10
40 #define PSA_PTR           0x00
41 #define CSD_OFFSET        0x294
42
43 /*
44     Long-term average CPU service used by this logical partition,
45     in millions of service units per hour. If this value is above
46     the partition's defined capacity, the partition will be capped.
47     It is calculated using the physical CPU adjustment factor
48     (RCTPCPUA) so it may not match other measures of service which
49     are based on the logical CPU adjustment factor. It is available
50     if the hardware supports LPAR cluster.
51 */
52 #define RCTLACS_OFFSET    0xC4
53
54 /* 32-bit count of alive CPUs. This includes both CPs and IFAs */
55 #define CSD_NUMBER_ONLINE_CPUS        0xD4
56
57 /* Address of system resources manager (SRM) control table */
58 #define CVTOPCTP_OFFSET   0x25C
59
60 /* Address of the RCT table */
61 #define RMCTRCT_OFFSET    0xE4
62
63 /* Address of the rsm control and enumeration area. */
64 #define CVTRCEP_OFFSET    0x490
65
66 /* Total number of frames currently on all available frame queues. */
67 #define RCEAFC_OFFSET     0x088
68
69 /* CPC model length from the CSRSI Service. */
70 #define CPCMODEL_LENGTH   16
71
72 /* Pointer to the home (current) ASCB. */
73 #define PSAAOLD           0x224
74
75 /* Pointer to rsm address space block extension. */
76 #define ASCBRSME          0x16C
77
78 /*
79     NUMBER OF FRAMES CURRENTLY IN USE BY THIS ADDRESS SPACE.
80     It does not include 2G frames.
81 */
82 #define RAXFMCT           0x2C
83
84 /* Thread Entry constants */
85 #define PGTH_CURRENT  1
86 #define PGTH_LEN      26
87 #define PGTHAPATH     0x20
88 #pragma linkage(BPX4GTH, OS)
89 #pragma linkage(BPX1GTH, OS)
90
91 /* TOD Clock resolution in nanoseconds */
92 #define TOD_RES 4.096
93
94 typedef unsigned data_area_ptr_assign_type;
95
96 typedef union {
97   struct {
98 #if defined(_LP64)
99     data_area_ptr_assign_type lower;
100 #endif
101     data_area_ptr_assign_type assign;
102   };
103   char* deref;
104 } data_area_ptr;
105
106
107 void uv_loadavg(double avg[3]) {
108   /* TODO: implement the following */
109   avg[0] = 0;
110   avg[1] = 0;
111   avg[2] = 0;
112 }
113
114
115 int uv__platform_loop_init(uv_loop_t* loop) {
116   uv__os390_epoll* ep;
117
118   ep = epoll_create1(0);
119   loop->ep = ep;
120   if (ep == NULL)
121     return UV__ERR(errno);
122
123   return 0;
124 }
125
126
127 void uv__platform_loop_delete(uv_loop_t* loop) {
128   if (loop->ep != NULL) {
129     epoll_queue_close(loop->ep);
130     loop->ep = NULL;
131   }
132 }
133
134
135 uint64_t uv__hrtime(uv_clocktype_t type) {
136   unsigned long long timestamp;
137   __stckf(&timestamp);
138   /* Convert to nanoseconds */
139   return timestamp / TOD_RES;
140 }
141
142
143 static int getexe(char* buf, size_t len) {
144   return uv__strscpy(buf, __getargv()[0], len);
145 }
146
147
148 /*
149  * We could use a static buffer for the path manipulations that we need outside
150  * of the function, but this function could be called by multiple consumers and
151  * we don't want to potentially create a race condition in the use of snprintf.
152  * There is no direct way of getting the exe path in zOS - either through /procfs
153  * or through some libc APIs. The below approach is to parse the argv[0]'s pattern
154  * and use it in conjunction with PATH environment variable to craft one.
155  */
156 int uv_exepath(char* buffer, size_t* size) {
157   int res;
158   char args[PATH_MAX];
159   int pid;
160
161   if (buffer == NULL || size == NULL || *size == 0)
162     return UV_EINVAL;
163
164   res = getexe(args, sizeof(args));
165   if (res < 0)
166     return UV_EINVAL;
167
168   return uv__search_path(args, buffer, size);
169 }
170
171
172 uint64_t uv_get_free_memory(void) {
173   uint64_t freeram;
174
175   data_area_ptr cvt = {0};
176   data_area_ptr rcep = {0};
177   cvt.assign = *(data_area_ptr_assign_type*)(CVT_PTR);
178   rcep.assign = *(data_area_ptr_assign_type*)(cvt.deref + CVTRCEP_OFFSET);
179   freeram = (uint64_t)*((uint32_t*)(rcep.deref + RCEAFC_OFFSET)) * 4096;
180   return freeram;
181 }
182
183
184 uint64_t uv_get_total_memory(void) {
185   /* Use CVTRLSTG to get the size of actual real storage online at IPL in K. */
186   return (uint64_t)((int)((char *__ptr32 *__ptr32 *)0)[4][214]) * 1024;
187 }
188
189
190 uint64_t uv_get_constrained_memory(void) {
191   struct rlimit rl;
192
193   /* RLIMIT_MEMLIMIT return value is in megabytes rather than bytes. */
194   if (getrlimit(RLIMIT_MEMLIMIT, &rl) == 0)
195     return rl.rlim_cur * 1024 * 1024;
196
197   return 0; /* There is no memory limit set. */
198 }
199
200
201 int uv_resident_set_memory(size_t* rss) {
202   char* ascb;
203   char* rax;
204   size_t nframes;
205
206   ascb  = *(char* __ptr32 *)(PSA_PTR + PSAAOLD);
207   rax = *(char* __ptr32 *)(ascb + ASCBRSME);
208   nframes = *(unsigned int*)(rax + RAXFMCT);
209
210   *rss = nframes * sysconf(_SC_PAGESIZE);
211   return 0;
212 }
213
214
215 int uv_uptime(double* uptime) {
216   struct utmpx u ;
217   struct utmpx *v;
218   time64_t t;
219
220   u.ut_type = BOOT_TIME;
221   v = getutxid(&u);
222   if (v == NULL)
223     return -1;
224   *uptime = difftime64(time64(&t), v->ut_tv.tv_sec);
225   return 0;
226 }
227
228
229 int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
230   uv_cpu_info_t* cpu_info;
231   int idx;
232   siv1v2 info;
233   data_area_ptr cvt = {0};
234   data_area_ptr csd = {0};
235   data_area_ptr rmctrct = {0};
236   data_area_ptr cvtopctp = {0};
237   int cpu_usage_avg;
238
239   cvt.assign = *(data_area_ptr_assign_type*)(CVT_PTR);
240
241   csd.assign = *((data_area_ptr_assign_type *) (cvt.deref + CSD_OFFSET));
242   cvtopctp.assign = *((data_area_ptr_assign_type *) (cvt.deref + CVTOPCTP_OFFSET));
243   rmctrct.assign = *((data_area_ptr_assign_type *) (cvtopctp.deref + RMCTRCT_OFFSET));
244
245   *count = *((int*) (csd.deref + CSD_NUMBER_ONLINE_CPUS));
246   cpu_usage_avg = *((unsigned short int*) (rmctrct.deref + RCTLACS_OFFSET));
247
248   *cpu_infos = uv__malloc(*count * sizeof(uv_cpu_info_t));
249   if (!*cpu_infos)
250     return UV_ENOMEM;
251
252   cpu_info = *cpu_infos;
253   idx = 0;
254   while (idx < *count) {
255     cpu_info->speed = *(int*)(info.siv1v2si22v1.si22v1cpucapability);
256     cpu_info->model = uv__malloc(CPCMODEL_LENGTH + 1);
257     memset(cpu_info->model, '\0', CPCMODEL_LENGTH + 1);
258     memcpy(cpu_info->model, info.siv1v2si11v1.si11v1cpcmodel, CPCMODEL_LENGTH);
259     cpu_info->cpu_times.user = cpu_usage_avg;
260     /* TODO: implement the following */
261     cpu_info->cpu_times.sys = 0;
262     cpu_info->cpu_times.idle = 0;
263     cpu_info->cpu_times.irq = 0;
264     cpu_info->cpu_times.nice = 0;
265     ++cpu_info;
266     ++idx;
267   }
268
269   return 0;
270 }
271
272
273 static int uv__interface_addresses_v6(uv_interface_address_t** addresses,
274                                       int* count) {
275   uv_interface_address_t* address;
276   int sockfd;
277   int maxsize;
278   __net_ifconf6header_t ifc;
279   __net_ifconf6entry_t* ifr;
280   __net_ifconf6entry_t* p;
281   __net_ifconf6entry_t flg;
282
283   *count = 0;
284   /* Assume maximum buffer size allowable */
285   maxsize = 16384;
286
287   if (0 > (sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP)))
288     return UV__ERR(errno);
289
290   ifc.__nif6h_version = 1;
291   ifc.__nif6h_buflen = maxsize;
292   ifc.__nif6h_buffer = uv__calloc(1, maxsize);;
293
294   if (ioctl(sockfd, SIOCGIFCONF6, &ifc) == -1) {
295     uv__close(sockfd);
296     return UV__ERR(errno);
297   }
298
299
300   *count = 0;
301   ifr = (__net_ifconf6entry_t*)(ifc.__nif6h_buffer);
302   while ((char*)ifr < (char*)ifc.__nif6h_buffer + ifc.__nif6h_buflen) {
303     p = ifr;
304     ifr = (__net_ifconf6entry_t*)((char*)ifr + ifc.__nif6h_entrylen);
305
306     if (!(p->__nif6e_addr.sin6_family == AF_INET6 ||
307           p->__nif6e_addr.sin6_family == AF_INET))
308       continue;
309
310     if (!(p->__nif6e_flags & _NIF6E_FLAGS_ON_LINK_ACTIVE))
311       continue;
312
313     ++(*count);
314   }
315
316   /* Alloc the return interface structs */
317   *addresses = uv__malloc(*count * sizeof(uv_interface_address_t));
318   if (!(*addresses)) {
319     uv__close(sockfd);
320     return UV_ENOMEM;
321   }
322   address = *addresses;
323
324   ifr = (__net_ifconf6entry_t*)(ifc.__nif6h_buffer);
325   while ((char*)ifr < (char*)ifc.__nif6h_buffer + ifc.__nif6h_buflen) {
326     p = ifr;
327     ifr = (__net_ifconf6entry_t*)((char*)ifr + ifc.__nif6h_entrylen);
328
329     if (!(p->__nif6e_addr.sin6_family == AF_INET6 ||
330           p->__nif6e_addr.sin6_family == AF_INET))
331       continue;
332
333     if (!(p->__nif6e_flags & _NIF6E_FLAGS_ON_LINK_ACTIVE))
334       continue;
335
336     /* All conditions above must match count loop */
337
338     address->name = uv__strdup(p->__nif6e_name);
339
340     if (p->__nif6e_addr.sin6_family == AF_INET6)
341       address->address.address6 = *((struct sockaddr_in6*) &p->__nif6e_addr);
342     else
343       address->address.address4 = *((struct sockaddr_in*) &p->__nif6e_addr);
344
345     /* TODO: Retrieve netmask using SIOCGIFNETMASK ioctl */
346
347     address->is_internal = flg.__nif6e_flags & _NIF6E_FLAGS_LOOPBACK ? 1 : 0;
348     memset(address->phys_addr, 0, sizeof(address->phys_addr));
349     address++;
350   }
351
352   uv__close(sockfd);
353   return 0;
354 }
355
356
357 int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
358   uv_interface_address_t* address;
359   int sockfd;
360   int maxsize;
361   struct ifconf ifc;
362   struct ifreq flg;
363   struct ifreq* ifr;
364   struct ifreq* p;
365   int count_v6;
366
367   *count = 0;
368   *addresses = NULL;
369
370   /* get the ipv6 addresses first */
371   uv_interface_address_t* addresses_v6;
372   uv__interface_addresses_v6(&addresses_v6, &count_v6);
373
374   /* now get the ipv4 addresses */
375
376   /* Assume maximum buffer size allowable */
377   maxsize = 16384;
378
379   sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
380   if (0 > sockfd)
381     return UV__ERR(errno);
382
383   ifc.ifc_req = uv__calloc(1, maxsize);
384   ifc.ifc_len = maxsize;
385   if (ioctl(sockfd, SIOCGIFCONF, &ifc) == -1) {
386     uv__close(sockfd);
387     return UV__ERR(errno);
388   }
389
390 #define MAX(a,b) (((a)>(b))?(a):(b))
391 #define ADDR_SIZE(p) MAX((p).sa_len, sizeof(p))
392
393   /* Count all up and running ipv4/ipv6 addresses */
394   ifr = ifc.ifc_req;
395   while ((char*)ifr < (char*)ifc.ifc_req + ifc.ifc_len) {
396     p = ifr;
397     ifr = (struct ifreq*)
398       ((char*)ifr + sizeof(ifr->ifr_name) + ADDR_SIZE(ifr->ifr_addr));
399
400     if (!(p->ifr_addr.sa_family == AF_INET6 ||
401           p->ifr_addr.sa_family == AF_INET))
402       continue;
403
404     memcpy(flg.ifr_name, p->ifr_name, sizeof(flg.ifr_name));
405     if (ioctl(sockfd, SIOCGIFFLAGS, &flg) == -1) {
406       uv__close(sockfd);
407       return UV__ERR(errno);
408     }
409
410     if (!(flg.ifr_flags & IFF_UP && flg.ifr_flags & IFF_RUNNING))
411       continue;
412
413     (*count)++;
414   }
415
416   if (*count == 0) {
417     uv__close(sockfd);
418     return 0;
419   }
420
421   /* Alloc the return interface structs */
422   *addresses = uv__malloc((*count + count_v6) *
423                           sizeof(uv_interface_address_t));
424
425   if (!(*addresses)) {
426     uv__close(sockfd);
427     return UV_ENOMEM;
428   }
429   address = *addresses;
430
431   /* copy over the ipv6 addresses */
432   memcpy(address, addresses_v6, count_v6 * sizeof(uv_interface_address_t));
433   address += count_v6;
434   *count += count_v6;
435   uv__free(addresses_v6);
436
437   ifr = ifc.ifc_req;
438   while ((char*)ifr < (char*)ifc.ifc_req + ifc.ifc_len) {
439     p = ifr;
440     ifr = (struct ifreq*)
441       ((char*)ifr + sizeof(ifr->ifr_name) + ADDR_SIZE(ifr->ifr_addr));
442
443     if (!(p->ifr_addr.sa_family == AF_INET6 ||
444           p->ifr_addr.sa_family == AF_INET))
445       continue;
446
447     memcpy(flg.ifr_name, p->ifr_name, sizeof(flg.ifr_name));
448     if (ioctl(sockfd, SIOCGIFFLAGS, &flg) == -1) {
449       uv__close(sockfd);
450       return UV_ENOSYS;
451     }
452
453     if (!(flg.ifr_flags & IFF_UP && flg.ifr_flags & IFF_RUNNING))
454       continue;
455
456     /* All conditions above must match count loop */
457
458     address->name = uv__strdup(p->ifr_name);
459
460     if (p->ifr_addr.sa_family == AF_INET6) {
461       address->address.address6 = *((struct sockaddr_in6*) &p->ifr_addr);
462     } else {
463       address->address.address4 = *((struct sockaddr_in*) &p->ifr_addr);
464     }
465
466     address->is_internal = flg.ifr_flags & IFF_LOOPBACK ? 1 : 0;
467     memset(address->phys_addr, 0, sizeof(address->phys_addr));
468     address++;
469   }
470
471 #undef ADDR_SIZE
472 #undef MAX
473
474   uv__close(sockfd);
475   return 0;
476 }
477
478
479 void uv_free_interface_addresses(uv_interface_address_t* addresses,
480                                  int count) {
481   int i;
482   for (i = 0; i < count; ++i)
483     uv__free(addresses[i].name);
484   uv__free(addresses);
485 }
486
487
488 void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) {
489   struct epoll_event* events;
490   struct epoll_event dummy;
491   uintptr_t i;
492   uintptr_t nfds;
493
494   assert(loop->watchers != NULL);
495   assert(fd >= 0);
496
497   events = (struct epoll_event*) loop->watchers[loop->nwatchers];
498   nfds = (uintptr_t) loop->watchers[loop->nwatchers + 1];
499   if (events != NULL)
500     /* Invalidate events with same file descriptor */
501     for (i = 0; i < nfds; i++)
502       if ((int) events[i].fd == fd)
503         events[i].fd = -1;
504
505   /* Remove the file descriptor from the epoll. */
506   if (loop->ep != NULL)
507     epoll_ctl(loop->ep, EPOLL_CTL_DEL, fd, &dummy);
508 }
509
510
511 int uv__io_check_fd(uv_loop_t* loop, int fd) {
512   struct pollfd p[1];
513   int rv;
514
515   p[0].fd = fd;
516   p[0].events = POLLIN;
517
518   do
519     rv = poll(p, 1, 0);
520   while (rv == -1 && errno == EINTR);
521
522   if (rv == -1)
523     abort();
524
525   if (p[0].revents & POLLNVAL)
526     return -1;
527
528   return 0;
529 }
530
531
532 void uv__fs_event_close(uv_fs_event_t* handle) {
533   uv_fs_event_stop(handle);
534 }
535
536
537 int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle) {
538   uv__handle_init(loop, (uv_handle_t*)handle, UV_FS_EVENT);
539   return 0;
540 }
541
542
543 int uv_fs_event_start(uv_fs_event_t* handle, uv_fs_event_cb cb,
544                       const char* filename, unsigned int flags) {
545   uv__os390_epoll* ep;
546   _RFIS reg_struct;
547   char* path;
548   int rc;
549
550   if (uv__is_active(handle))
551     return UV_EINVAL;
552
553   ep = handle->loop->ep;
554   assert(ep->msg_queue != -1);
555
556   reg_struct.__rfis_cmd  = _RFIS_REG;
557   reg_struct.__rfis_qid  = ep->msg_queue;
558   reg_struct.__rfis_type = 1;
559   memcpy(reg_struct.__rfis_utok, &handle, sizeof(handle));
560
561   path = uv__strdup(filename);
562   if (path == NULL)
563     return UV_ENOMEM;
564
565   rc = __w_pioctl(path, _IOCC_REGFILEINT, sizeof(reg_struct), &reg_struct);
566   if (rc != 0)
567     return UV__ERR(errno);
568
569   uv__handle_start(handle);
570   handle->path = path;
571   handle->cb = cb;
572   memcpy(handle->rfis_rftok, reg_struct.__rfis_rftok,
573          sizeof(handle->rfis_rftok));
574
575   return 0;
576 }
577
578
579 int uv_fs_event_stop(uv_fs_event_t* handle) {
580   uv__os390_epoll* ep;
581   _RFIS reg_struct;
582   int rc;
583
584   if (!uv__is_active(handle))
585     return 0;
586
587   ep = handle->loop->ep;
588   assert(ep->msg_queue != -1);
589
590   reg_struct.__rfis_cmd  = _RFIS_UNREG;
591   reg_struct.__rfis_qid  = ep->msg_queue;
592   reg_struct.__rfis_type = 1;
593   memcpy(reg_struct.__rfis_rftok, handle->rfis_rftok,
594          sizeof(handle->rfis_rftok));
595
596   /*
597    * This call will take "/" as the path argument in case we
598    * don't care to supply the correct path. The system will simply
599    * ignore it.
600    */
601   rc = __w_pioctl("/", _IOCC_REGFILEINT, sizeof(reg_struct), &reg_struct);
602   if (rc != 0 && errno != EALREADY && errno != ENOENT)
603     abort();
604
605   uv__handle_stop(handle);
606
607   return 0;
608 }
609
610
611 static int os390_message_queue_handler(uv__os390_epoll* ep) {
612   uv_fs_event_t* handle;
613   int msglen;
614   int events;
615   _RFIM msg;
616
617   if (ep->msg_queue == -1)
618     return 0;
619
620   msglen = msgrcv(ep->msg_queue, &msg, sizeof(msg), 0, IPC_NOWAIT);
621
622   if (msglen == -1 && errno == ENOMSG)
623     return 0;
624
625   if (msglen == -1)
626     abort();
627
628   events = 0;
629   if (msg.__rfim_event == _RFIM_ATTR || msg.__rfim_event == _RFIM_WRITE)
630     events = UV_CHANGE;
631   else if (msg.__rfim_event == _RFIM_RENAME)
632     events = UV_RENAME;
633   else
634     /* Some event that we are not interested in. */
635     return 0;
636
637   /* `__rfim_utok` is treated as text when it should be treated as binary while
638    * running in ASCII mode, resulting in an unwanted autoconversion.
639    */
640   __a2e_l(msg.__rfim_utok, sizeof(msg.__rfim_utok));
641   handle = *(uv_fs_event_t**)(msg.__rfim_utok);
642   handle->cb(handle, uv__basename_r(handle->path), events, 0);
643   return 1;
644 }
645
646
647 void uv__io_poll(uv_loop_t* loop, int timeout) {
648   static const int max_safe_timeout = 1789569;
649   struct epoll_event events[1024];
650   struct epoll_event* pe;
651   struct epoll_event e;
652   uv__os390_epoll* ep;
653   int real_timeout;
654   QUEUE* q;
655   uv__io_t* w;
656   uint64_t base;
657   int count;
658   int nfds;
659   int fd;
660   int op;
661   int i;
662   int user_timeout;
663   int reset_timeout;
664
665   if (loop->nfds == 0) {
666     assert(QUEUE_EMPTY(&loop->watcher_queue));
667     return;
668   }
669
670   while (!QUEUE_EMPTY(&loop->watcher_queue)) {
671     uv_stream_t* stream;
672
673     q = QUEUE_HEAD(&loop->watcher_queue);
674     QUEUE_REMOVE(q);
675     QUEUE_INIT(q);
676     w = QUEUE_DATA(q, uv__io_t, watcher_queue);
677
678     assert(w->pevents != 0);
679     assert(w->fd >= 0);
680
681     stream= container_of(w, uv_stream_t, io_watcher);
682
683     assert(w->fd < (int) loop->nwatchers);
684
685     e.events = w->pevents;
686     e.fd = w->fd;
687
688     if (w->events == 0)
689       op = EPOLL_CTL_ADD;
690     else
691       op = EPOLL_CTL_MOD;
692
693     /* XXX Future optimization: do EPOLL_CTL_MOD lazily if we stop watching
694      * events, skip the syscall and squelch the events after epoll_wait().
695      */
696     if (epoll_ctl(loop->ep, op, w->fd, &e)) {
697       if (errno != EEXIST)
698         abort();
699
700       assert(op == EPOLL_CTL_ADD);
701
702       /* We've reactivated a file descriptor that's been watched before. */
703       if (epoll_ctl(loop->ep, EPOLL_CTL_MOD, w->fd, &e))
704         abort();
705     }
706
707     w->events = w->pevents;
708   }
709
710   assert(timeout >= -1);
711   base = loop->time;
712   count = 48; /* Benchmarks suggest this gives the best throughput. */
713   real_timeout = timeout;
714   int nevents = 0;
715
716   if (uv__get_internal_fields(loop)->flags & UV_METRICS_IDLE_TIME) {
717     reset_timeout = 1;
718     user_timeout = timeout;
719     timeout = 0;
720   } else {
721     reset_timeout = 0;
722   }
723
724   nfds = 0;
725   for (;;) {
726     /* Only need to set the provider_entry_time if timeout != 0. The function
727      * will return early if the loop isn't configured with UV_METRICS_IDLE_TIME.
728      */
729     if (timeout != 0)
730       uv__metrics_set_provider_entry_time(loop);
731
732     if (sizeof(int32_t) == sizeof(long) && timeout >= max_safe_timeout)
733       timeout = max_safe_timeout;
734
735     nfds = epoll_wait(loop->ep, events,
736                       ARRAY_SIZE(events), timeout);
737
738     /* Update loop->time unconditionally. It's tempting to skip the update when
739      * timeout == 0 (i.e. non-blocking poll) but there is no guarantee that the
740      * operating system didn't reschedule our process while in the syscall.
741      */
742     base = loop->time;
743     SAVE_ERRNO(uv__update_time(loop));
744     if (nfds == 0) {
745       assert(timeout != -1);
746
747       if (reset_timeout != 0) {
748         timeout = user_timeout;
749         reset_timeout = 0;
750       }
751
752       if (timeout == -1)
753         continue;
754
755       if (timeout == 0)
756         return;
757
758       /* We may have been inside the system call for longer than |timeout|
759        * milliseconds so we need to update the timestamp to avoid drift.
760        */
761       goto update_timeout;
762     }
763
764     if (nfds == -1) {
765
766       if (errno != EINTR)
767         abort();
768
769       if (reset_timeout != 0) {
770         timeout = user_timeout;
771         reset_timeout = 0;
772       }
773
774       if (timeout == -1)
775         continue;
776
777       if (timeout == 0)
778         return;
779
780       /* Interrupted by a signal. Update timeout and poll again. */
781       goto update_timeout;
782     }
783
784
785     assert(loop->watchers != NULL);
786     loop->watchers[loop->nwatchers] = (void*) events;
787     loop->watchers[loop->nwatchers + 1] = (void*) (uintptr_t) nfds;
788     for (i = 0; i < nfds; i++) {
789       pe = events + i;
790       fd = pe->fd;
791
792       /* Skip invalidated events, see uv__platform_invalidate_fd */
793       if (fd == -1)
794         continue;
795
796       ep = loop->ep;
797       if (pe->is_msg) {
798         os390_message_queue_handler(ep);
799         continue;
800       }
801
802       assert(fd >= 0);
803       assert((unsigned) fd < loop->nwatchers);
804
805       w = loop->watchers[fd];
806
807       if (w == NULL) {
808         /* File descriptor that we've stopped watching, disarm it.
809          *
810          * Ignore all errors because we may be racing with another thread
811          * when the file descriptor is closed.
812          */
813         epoll_ctl(loop->ep, EPOLL_CTL_DEL, fd, pe);
814         continue;
815       }
816
817       /* Give users only events they're interested in. Prevents spurious
818        * callbacks when previous callback invocation in this loop has stopped
819        * the current watcher. Also, filters out events that users has not
820        * requested us to watch.
821        */
822       pe->events &= w->pevents | POLLERR | POLLHUP;
823
824       if (pe->events == POLLERR || pe->events == POLLHUP)
825         pe->events |= w->pevents & (POLLIN | POLLOUT);
826
827       if (pe->events != 0) {
828         uv__metrics_update_idle_time(loop);
829         w->cb(loop, w, pe->events);
830         nevents++;
831       }
832     }
833     loop->watchers[loop->nwatchers] = NULL;
834     loop->watchers[loop->nwatchers + 1] = NULL;
835
836     if (reset_timeout != 0) {
837       timeout = user_timeout;
838       reset_timeout = 0;
839     }
840
841     if (nevents != 0) {
842       if (nfds == ARRAY_SIZE(events) && --count != 0) {
843         /* Poll for more events but don't block this time. */
844         timeout = 0;
845         continue;
846       }
847       return;
848     }
849
850     if (timeout == 0)
851       return;
852
853     if (timeout == -1)
854       continue;
855
856 update_timeout:
857     assert(timeout > 0);
858
859     real_timeout -= (loop->time - base);
860     if (real_timeout <= 0)
861       return;
862
863     timeout = real_timeout;
864   }
865 }
866
867
868 int uv__io_fork(uv_loop_t* loop) {
869   /*
870     Nullify the msg queue but don't close it because
871     it is still being used by the parent.
872   */
873   loop->ep = NULL;
874
875   uv__platform_loop_delete(loop);
876   return uv__platform_loop_init(loop);
877 }