1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
$NetBSD: patch-ac,v 1.7 2010/08/06 19:21:27 drochner Exp $
--- pth_high.c.orig 2006-06-08 17:54:03.000000000 +0000
+++ pth_high.c
@@ -184,6 +184,35 @@ int pth_sigwait_ev(const sigset_t *set,
return 0;
}
+#ifdef HAVE_SYS_RESOURCE_H
+/* Pth variant of wait4(2) */
+pid_t pth_wait4(pid_t wpid, int *status, int options, struct rusage *rusage)
+{
+ pth_event_t ev;
+ static pth_key_t ev_key = PTH_KEY_INIT;
+ pid_t pid;
+
+ pth_debug2("pth_wait4: called from thread \"%s\"", pth_current->name);
+
+ for (;;) {
+ /* do a non-blocking poll for the pid */
+ while ( (pid = pth_sc(wait4)(wpid, status, options|WNOHANG, rusage)) < 0
+ && errno == EINTR) ;
+
+ /* if pid was found or caller requested a polling return immediately */
+ if (pid == -1 || pid > 0 || (pid == 0 && (options & WNOHANG)))
+ break;
+
+ /* else wait a little bit */
+ ev = pth_event(PTH_EVENT_TIME|PTH_MODE_STATIC, &ev_key, pth_timeout(0,250000));
+ pth_wait(ev);
+ }
+
+ pth_debug2("pth_wait4: leave to thread \"%s\"", pth_current->name);
+ return pid;
+}
+#endif
+
/* Pth variant of waitpid(2) */
pid_t pth_waitpid(pid_t wpid, int *status, int options)
{
@@ -334,9 +363,9 @@ int pth_select_ev(int nfd, fd_set *rfds,
}
}
/* POSIX.1-2001/SUSv3 compliance */
- if (rfds != NULL) FD_ZERO(rfds);
- if (wfds != NULL) FD_ZERO(wfds);
- if (efds != NULL) FD_ZERO(efds);
+ if (rfds != NULL) pth_util_fd_zero(nfd, rfds);
+ if (wfds != NULL) pth_util_fd_zero(nfd, wfds);
+ if (efds != NULL) pth_util_fd_zero(nfd, efds);
return 0;
}
@@ -349,17 +378,17 @@ int pth_select_ev(int nfd, fd_set *rfds,
delay.tv_usec = 0;
rtmp = NULL;
if (rfds != NULL) {
- memcpy(&rspare, rfds, sizeof(fd_set));
+ pth_util_fd_copy(nfd, &rspare, rfds);
rtmp = &rspare;
}
wtmp = NULL;
if (wfds != NULL) {
- memcpy(&wspare, wfds, sizeof(fd_set));
+ pth_util_fd_copy(nfd, &wspare, wfds);
wtmp = &wspare;
}
etmp = NULL;
if (efds != NULL) {
- memcpy(&espare, efds, sizeof(fd_set));
+ pth_util_fd_copy(nfd, &espare, efds);
etmp = &espare;
}
while ((rc = pth_sc(select)(nfd, rtmp, wtmp, etmp, &delay)) < 0
@@ -374,11 +403,11 @@ int pth_select_ev(int nfd, fd_set *rfds,
&& pth_time_cmp(timeout, PTH_TIME_ZERO) == 0)) {
/* pass-through immediate success */
if (rfds != NULL)
- memcpy(rfds, &rspare, sizeof(fd_set));
+ pth_util_fd_copy(nfd, rfds, &rspare);
if (wfds != NULL)
- memcpy(wfds, &wspare, sizeof(fd_set));
+ pth_util_fd_copy(nfd, wfds, &wspare);
if (efds != NULL)
- memcpy(efds, &espare, sizeof(fd_set));
+ pth_util_fd_copy(nfd, efds, &espare);
return rc;
}
@@ -411,9 +440,9 @@ int pth_select_ev(int nfd, fd_set *rfds,
&& pth_event_status(ev_timeout) == PTH_STATUS_OCCURRED) {
selected = TRUE;
/* POSIX.1-2001/SUSv3 compliance */
- if (rfds != NULL) FD_ZERO(rfds);
- if (wfds != NULL) FD_ZERO(wfds);
- if (efds != NULL) FD_ZERO(efds);
+ if (rfds != NULL) pth_util_fd_zero(nfd, rfds);
+ if (wfds != NULL) pth_util_fd_zero(nfd, wfds);
+ if (efds != NULL) pth_util_fd_zero(nfd, efds);
rc = 0;
}
if (ev_extra != NULL && !selected)
@@ -601,6 +630,7 @@ int pth_connect_ev(int s, const struct s
int rv, err;
socklen_t errlen;
int fdmode;
+ int notfirsttry = 0;
pth_implicit_init();
pth_debug2("pth_connect_ev: enter from thread \"%s\"", pth_current->name);
@@ -615,8 +645,11 @@ int pth_connect_ev(int s, const struct s
/* try to connect */
while ( (rv = pth_sc(connect)(s, (struct sockaddr *)addr, addrlen)) == -1
- && errno == EINTR)
+ && (errno == EINTR || errno == EINPROGRESS || errno == EALREADY))
+ notfirsttry = 1;
;
+ if (rv == -1 && errno == EISCONN && notfirsttry)
+ rv = 0;
/* restore filedescriptor mode */
pth_shield { pth_fdmode(s, fdmode); }
@@ -624,6 +657,13 @@ int pth_connect_ev(int s, const struct s
/* if it is still on progress wait until socket is really writeable */
if (rv == -1 && errno == EINPROGRESS && fdmode != PTH_FDMODE_NONBLOCK) {
if ((ev = pth_event(PTH_EVENT_FD|PTH_UNTIL_FD_WRITEABLE|PTH_MODE_STATIC, &ev_key, s)) == NULL)
+ /*
+ * This will fail if the fd is > FD_SETSIZE so pass the error back to the
+ * caller.
+ */
+ if (ev == NULL) {
+ return pth_error(-1, errno);
+ }
return pth_error(-1, errno);
if (ev_extra != NULL)
pth_event_concat(ev, ev_extra, NULL);
|