1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20: #include <errno.h>
21: #include <netdb.h>
22: #include <pthread.h>
23: #include <stdlib.h>
24: #include <sys/time.h>
25:
26: #include <gai_misc.h>
27:
28:
29: int
30: gai_suspend (const struct gaicb *const list[], int ent,
31: const struct timespec *timeout)
32: {
33: struct waitlist waitlist[ent];
34: struct requestlist *requestlist[ent];
35: #ifndef DONT_NEED_GAI_MISC_COND
36: pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
37: #endif
38: int cnt;
39: int cntr = 1;
40: int none = 1;
41: int result;
42:
43:
44: pthread_mutex_lock (&__gai_requests_mutex);
45:
46:
47:
48: for (cnt = 0; cnt < ent; ++cnt)
49: if (list[cnt] != NULL && list[cnt]->__return == EAI_INPROGRESS)
50: {
51: requestlist[cnt] = __gai_find_request (list[cnt]);
52:
53: if (requestlist[cnt] != NULL)
54: {
55: #ifndef DONT_NEED_GAI_MISC_COND
56: waitlist[cnt].cond = &cond;
57: #endif
58: waitlist[cnt].next = requestlist[cnt]->waiting;
59: waitlist[cnt].counterp = &cntr;
60: waitlist[cnt].sigevp = NULL;
61: waitlist[cnt].caller_pid = 0;
62: requestlist[cnt]->waiting = &waitlist[cnt];
63: none = 0;
64: }
65: }
66:
67: if (none)
68: {
69: if (cnt < ent)
70:
71: result = 0;
72: else
73: result = EAI_ALLDONE;
74: }
75: else
76: {
77:
78: int oldstate;
79:
80:
81:
82:
83: pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &oldstate);
84:
85: #ifdef DONT_NEED_GAI_MISC_COND
86: result = 0;
87: GAI_MISC_WAIT (result, cntr, timeout, 1);
88: #else
89: if (timeout == NULL)
90: result = pthread_cond_wait (&cond, &__gai_requests_mutex);
91: else
92: {
93:
94:
95: struct timeval now;
96: struct timespec abstime;
97:
98: __gettimeofday (&now, NULL);
99: abstime.tv_nsec = timeout->tv_nsec + now.tv_usec * 1000;
100: abstime.tv_sec = timeout->tv_sec + now.tv_sec;
101: if (abstime.tv_nsec >= 1000000000)
102: {
103: abstime.tv_nsec -= 1000000000;
104: abstime.tv_sec += 1;
105: }
106:
107: result = pthread_cond_timedwait (&cond, &__gai_requests_mutex,
108: &abstime);
109: }
110: #endif
111:
112:
113:
114: for (cnt = 0; cnt < ent; ++cnt)
115: if (list[cnt] != NULL && list[cnt]->__return == EAI_INPROGRESS
116: && requestlist[cnt] != NULL)
117: {
118: struct waitlist **listp = &requestlist[cnt]->waiting;
119:
120:
121:
122:
123: while (*listp != NULL && *listp != &waitlist[cnt])
124: listp = &(*listp)->next;
125:
126: if (*listp != NULL)
127: *listp = (*listp)->next;
128: }
129:
130:
131: pthread_setcancelstate (oldstate, NULL);
132:
133: #ifndef DONT_NEED_GAI_MISC_COND
134:
135: if (pthread_cond_destroy (&cond) != 0)
136:
137: abort ();
138: #endif
139:
140: if (result != 0)
141: {
142:
143:
144:
145: if (__builtin_expect (result, ETIMEDOUT) == ETIMEDOUT)
146: result = EAI_AGAIN;
147: else if (result == EINTR)
148: result = EAI_INTR;
149: else
150: result = EAI_SYSTEM;
151: }
152: }
153:
154:
155: pthread_mutex_unlock (&__gai_requests_mutex);
156:
157: return result;
158: }