1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20: #include <netdb.h>
21: #include <pthread.h>
22: #include <stdlib.h>
23: #include <gai_misc.h>
24:
25:
26: struct notify_func
27: {
28: void (*func) (sigval_t);
29: sigval_t value;
30: };
31:
32: static void *
33: notify_func_wrapper (void *arg)
34: {
35: gai_start_notify_thread ();
36: struct notify_func *const n = arg;
37: void (*func) (sigval_t) = n->func;
38: sigval_t value = n->value;
39: free (n);
40: (*func) (value);
41: return NULL;
42: }
43:
44:
45: int
46: internal_function
47: __gai_notify_only (struct sigevent *sigev, pid_t caller_pid)
48: {
49: int result = 0;
50:
51:
52: if (sigev->sigev_notify == SIGEV_THREAD)
53: {
54:
55: pthread_t tid;
56: pthread_attr_t attr, *pattr;
57:
58: pattr = (pthread_attr_t *) sigev->sigev_notify_attributes;
59: if (pattr == NULL)
60: {
61: pthread_attr_init (&attr);
62: pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
63: pattr = &attr;
64: }
65:
66:
67:
68:
69:
70:
71:
72:
73: struct notify_func *nf = malloc (sizeof *nf);
74: if (nf == NULL)
75: result = -1;
76: else
77: {
78: nf->func = sigev->sigev_notify_function;
79: nf->value = sigev->sigev_value;
80: if (pthread_create (&tid, pattr, notify_func_wrapper, nf) < 0)
81: {
82: free (nf);
83: result = -1;
84: }
85: }
86: }
87: else if (sigev->sigev_notify == SIGEV_SIGNAL)
88:
89: if (__gai_sigqueue (sigev->sigev_signo, sigev->sigev_value, caller_pid)
90: < 0)
91: result = -1;
92:
93: return result;
94: }
95:
96:
97: void
98: internal_function
99: __gai_notify (struct requestlist *req)
100: {
101: struct waitlist *waitlist;
102:
103:
104: waitlist = req->waiting;
105: while (waitlist != NULL)
106: {
107: struct waitlist *next = waitlist->next;
108:
109: if (waitlist->sigevp == NULL)
110: {
111: #ifdef DONT_NEED_GAI_MISC_COND
112: GAI_MISC_NOTIFY (waitlist);
113: #else
114:
115: --*waitlist->counterp;
116:
117: pthread_cond_signal (waitlist->cond);
118: #endif
119: }
120: else
121:
122:
123: if (--*waitlist->counterp == 0)
124: {
125: __gai_notify_only (waitlist->sigevp, waitlist->caller_pid);
126:
127:
128: free ((void *) waitlist->counterp);
129: }
130:
131: waitlist = next;
132: }
133: }