Mercurial > trustbridge > nss-cmake-static
comparison nspr/pr/src/io/prpolevt.c @ 0:1e5118fa0cb1
This is NSS with a Cmake Buildsyste
To compile a static NSS library for Windows we've used the
Chromium-NSS fork and added a Cmake buildsystem to compile
it statically for Windows. See README.chromium for chromium
changes and README.trustbridge for our modifications.
author | Andre Heinecke <andre.heinecke@intevation.de> |
---|---|
date | Mon, 28 Jul 2014 10:47:06 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:1e5118fa0cb1 |
---|---|
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ | |
2 /* This Source Code Form is subject to the terms of the Mozilla Public | |
3 * License, v. 2.0. If a copy of the MPL was not distributed with this | |
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | |
5 | |
6 /* | |
7 ********************************************************************* | |
8 * | |
9 * Pollable events | |
10 * | |
11 * Pollable events are implemented using layered I/O. The only | |
12 * I/O methods that are implemented for pollable events are poll | |
13 * and close. No other methods can be invoked on a pollable | |
14 * event. | |
15 * | |
16 * A pipe or socket pair is created and the pollable event layer | |
17 * is pushed onto the read end. A pointer to the write end is | |
18 * saved in the PRFilePrivate structure of the pollable event. | |
19 * | |
20 ********************************************************************* | |
21 */ | |
22 | |
23 #include "prinit.h" | |
24 #include "prio.h" | |
25 #include "prmem.h" | |
26 #include "prerror.h" | |
27 #include "prlog.h" | |
28 | |
29 /* | |
30 * These internal functions are declared in primpl.h, | |
31 * but we can't include primpl.h because the definition | |
32 * of struct PRFilePrivate in this file (for the pollable | |
33 * event layer) will conflict with the definition of | |
34 * struct PRFilePrivate in primpl.h (for the NSPR layer). | |
35 */ | |
36 extern PRIntn _PR_InvalidInt(void); | |
37 extern PRInt64 _PR_InvalidInt64(void); | |
38 extern PRStatus _PR_InvalidStatus(void); | |
39 extern PRFileDesc *_PR_InvalidDesc(void); | |
40 | |
41 /* | |
42 * PRFilePrivate structure for the NSPR pollable events layer | |
43 */ | |
44 struct PRFilePrivate { | |
45 PRFileDesc *writeEnd; /* the write end of the pipe/socketpair */ | |
46 }; | |
47 | |
48 static PRStatus PR_CALLBACK _pr_PolEvtClose(PRFileDesc *fd); | |
49 | |
50 static PRInt16 PR_CALLBACK _pr_PolEvtPoll( | |
51 PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags); | |
52 | |
53 static PRIOMethods _pr_polevt_methods = { | |
54 PR_DESC_LAYERED, | |
55 _pr_PolEvtClose, | |
56 (PRReadFN)_PR_InvalidInt, | |
57 (PRWriteFN)_PR_InvalidInt, | |
58 (PRAvailableFN)_PR_InvalidInt, | |
59 (PRAvailable64FN)_PR_InvalidInt64, | |
60 (PRFsyncFN)_PR_InvalidStatus, | |
61 (PRSeekFN)_PR_InvalidInt, | |
62 (PRSeek64FN)_PR_InvalidInt64, | |
63 (PRFileInfoFN)_PR_InvalidStatus, | |
64 (PRFileInfo64FN)_PR_InvalidStatus, | |
65 (PRWritevFN)_PR_InvalidInt, | |
66 (PRConnectFN)_PR_InvalidStatus, | |
67 (PRAcceptFN)_PR_InvalidDesc, | |
68 (PRBindFN)_PR_InvalidStatus, | |
69 (PRListenFN)_PR_InvalidStatus, | |
70 (PRShutdownFN)_PR_InvalidStatus, | |
71 (PRRecvFN)_PR_InvalidInt, | |
72 (PRSendFN)_PR_InvalidInt, | |
73 (PRRecvfromFN)_PR_InvalidInt, | |
74 (PRSendtoFN)_PR_InvalidInt, | |
75 _pr_PolEvtPoll, | |
76 (PRAcceptreadFN)_PR_InvalidInt, | |
77 (PRTransmitfileFN)_PR_InvalidInt, | |
78 (PRGetsocknameFN)_PR_InvalidStatus, | |
79 (PRGetpeernameFN)_PR_InvalidStatus, | |
80 (PRReservedFN)_PR_InvalidInt, | |
81 (PRReservedFN)_PR_InvalidInt, | |
82 (PRGetsocketoptionFN)_PR_InvalidStatus, | |
83 (PRSetsocketoptionFN)_PR_InvalidStatus, | |
84 (PRSendfileFN)_PR_InvalidInt, | |
85 (PRConnectcontinueFN)_PR_InvalidStatus, | |
86 (PRReservedFN)_PR_InvalidInt, | |
87 (PRReservedFN)_PR_InvalidInt, | |
88 (PRReservedFN)_PR_InvalidInt, | |
89 (PRReservedFN)_PR_InvalidInt | |
90 }; | |
91 | |
92 static PRDescIdentity _pr_polevt_id; | |
93 static PRCallOnceType _pr_polevt_once_control; | |
94 static PRStatus PR_CALLBACK _pr_PolEvtInit(void); | |
95 | |
96 static PRInt16 PR_CALLBACK _pr_PolEvtPoll( | |
97 PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags) | |
98 { | |
99 return (fd->lower->methods->poll)(fd->lower, in_flags, out_flags); | |
100 } | |
101 | |
102 static PRStatus PR_CALLBACK _pr_PolEvtInit(void) | |
103 { | |
104 _pr_polevt_id = PR_GetUniqueIdentity("NSPR pollable events"); | |
105 if (PR_INVALID_IO_LAYER == _pr_polevt_id) { | |
106 return PR_FAILURE; | |
107 } | |
108 return PR_SUCCESS; | |
109 } | |
110 | |
111 #if !defined(XP_UNIX) | |
112 #define USE_TCP_SOCKETPAIR | |
113 #endif | |
114 | |
115 PR_IMPLEMENT(PRFileDesc *) PR_NewPollableEvent(void) | |
116 { | |
117 PRFileDesc *event; | |
118 PRFileDesc *fd[2]; /* fd[0] is the read end; fd[1] is the write end */ | |
119 #ifdef USE_TCP_SOCKETPAIR | |
120 PRSocketOptionData socket_opt; | |
121 PRStatus rv; | |
122 #endif | |
123 | |
124 fd[0] = fd[1] = NULL; | |
125 | |
126 if (PR_CallOnce(&_pr_polevt_once_control, _pr_PolEvtInit) == PR_FAILURE) { | |
127 return NULL; | |
128 } | |
129 | |
130 event = PR_CreateIOLayerStub(_pr_polevt_id, &_pr_polevt_methods); | |
131 if (NULL == event) { | |
132 goto errorExit; | |
133 } | |
134 event->secret = PR_NEW(PRFilePrivate); | |
135 if (event->secret == NULL) { | |
136 PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); | |
137 goto errorExit; | |
138 } | |
139 | |
140 #ifndef USE_TCP_SOCKETPAIR | |
141 if (PR_CreatePipe(&fd[0], &fd[1]) == PR_FAILURE) { | |
142 fd[0] = fd[1] = NULL; | |
143 goto errorExit; | |
144 } | |
145 #else | |
146 if (PR_NewTCPSocketPair(fd) == PR_FAILURE) { | |
147 fd[0] = fd[1] = NULL; | |
148 goto errorExit; | |
149 } | |
150 /* | |
151 * set the TCP_NODELAY option to reduce notification latency | |
152 */ | |
153 socket_opt.option = PR_SockOpt_NoDelay; | |
154 socket_opt.value.no_delay = PR_TRUE; | |
155 rv = PR_SetSocketOption(fd[1], &socket_opt); | |
156 PR_ASSERT(PR_SUCCESS == rv); | |
157 #endif | |
158 | |
159 event->secret->writeEnd = fd[1]; | |
160 if (PR_PushIOLayer(fd[0], PR_TOP_IO_LAYER, event) == PR_FAILURE) { | |
161 goto errorExit; | |
162 } | |
163 | |
164 return fd[0]; | |
165 | |
166 errorExit: | |
167 if (fd[0]) { | |
168 PR_Close(fd[0]); | |
169 PR_Close(fd[1]); | |
170 } | |
171 if (event) { | |
172 PR_DELETE(event->secret); | |
173 event->dtor(event); | |
174 } | |
175 return NULL; | |
176 } | |
177 | |
178 static PRStatus PR_CALLBACK _pr_PolEvtClose(PRFileDesc *fd) | |
179 { | |
180 PRFileDesc *event; | |
181 | |
182 event = PR_PopIOLayer(fd, PR_TOP_IO_LAYER); | |
183 PR_ASSERT(NULL == event->higher && NULL == event->lower); | |
184 PR_Close(fd); | |
185 PR_Close(event->secret->writeEnd); | |
186 PR_DELETE(event->secret); | |
187 event->dtor(event); | |
188 return PR_SUCCESS; | |
189 } | |
190 | |
191 PR_IMPLEMENT(PRStatus) PR_DestroyPollableEvent(PRFileDesc *event) | |
192 { | |
193 return PR_Close(event); | |
194 } | |
195 | |
196 static const char magicChar = '\x38'; | |
197 | |
198 PR_IMPLEMENT(PRStatus) PR_SetPollableEvent(PRFileDesc *event) | |
199 { | |
200 if (PR_Write(event->secret->writeEnd, &magicChar, 1) != 1) { | |
201 return PR_FAILURE; | |
202 } | |
203 return PR_SUCCESS; | |
204 } | |
205 | |
206 PR_IMPLEMENT(PRStatus) PR_WaitForPollableEvent(PRFileDesc *event) | |
207 { | |
208 char buf[1024]; | |
209 PRInt32 nBytes; | |
210 #ifdef DEBUG | |
211 PRIntn i; | |
212 #endif | |
213 | |
214 nBytes = PR_Read(event->lower, buf, sizeof(buf)); | |
215 if (nBytes == -1) { | |
216 return PR_FAILURE; | |
217 } | |
218 | |
219 #ifdef DEBUG | |
220 /* | |
221 * Make sure people do not write to the pollable event fd | |
222 * directly. | |
223 */ | |
224 for (i = 0; i < nBytes; i++) { | |
225 PR_ASSERT(buf[i] == magicChar); | |
226 } | |
227 #endif | |
228 | |
229 return PR_SUCCESS; | |
230 } |