~ubuntu-branches/ubuntu/quantal/nspr/quantal-security

« back to all changes in this revision

Viewing changes to mozilla/nsprpub/pr/src/io/prpolevt.c

  • Committer: Bazaar Package Importer
  • Author(s): Alexander Sack
  • Date: 2009-08-10 11:34:26 UTC
  • mfrom: (1.1.10 upstream)
  • Revision ID: james.westby@ubuntu.com-20090810113426-3uv4diflrkcbdimm
Tags: 4.8-0ubuntu1
* New upstream release: 4.8 (LP: #387812)
* adjust patches to changed upstreanm codebase
  - update debian/patches/99_configure.patch
* update shlibs symbols to include new API elements
  - update debian/libnspr4-0d.symbols

Show diffs side-by-side

added added

removed removed

Lines of Context:
58
58
#include "prerror.h"
59
59
#include "prlog.h"
60
60
 
61
 
#ifdef VMS
62
 
 
63
 
/*
64
 
 * On OpenVMS we use an event flag instead of a pipe or a socket since
65
 
 * event flags are much more efficient on OpenVMS.
66
 
 */
67
 
#include "pprio.h"
68
 
#include <lib$routines.h>
69
 
#include <starlet.h>
70
 
#include <stsdef.h>
71
 
 
72
 
PR_IMPLEMENT(PRFileDesc *) PR_NewPollableEvent(void)
73
 
{
74
 
    unsigned int status;
75
 
    int flag = -1;
76
 
    PRFileDesc *event;
77
 
 
78
 
    /*
79
 
    ** Allocate an event flag and clear it.
80
 
    */
81
 
    status = lib$get_ef(&flag);
82
 
    if ((!$VMS_STATUS_SUCCESS(status)) || (flag == -1)) {
83
 
        PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, status);
84
 
        return NULL;
85
 
    }
86
 
    sys$clref(flag);
87
 
 
88
 
    /*
89
 
    ** Give NSPR the event flag's negative value. We do this because our
90
 
    ** select interprets a negative fd as an event flag rather than a
91
 
    ** regular file fd.
92
 
    */
93
 
    event = PR_CreateSocketPollFd(-flag);
94
 
    if (NULL == event) {
95
 
        lib$free_ef(&flag);
96
 
        return NULL;
97
 
    }
98
 
 
99
 
    return event;
100
 
}
101
 
 
102
 
PR_IMPLEMENT(PRStatus) PR_DestroyPollableEvent(PRFileDesc *event)
103
 
{
104
 
    int flag = -PR_FileDesc2NativeHandle(event);
105
 
    PR_DestroySocketPollFd(event);
106
 
    lib$free_ef(&flag);
107
 
    return PR_SUCCESS;
108
 
}
109
 
 
110
 
PR_IMPLEMENT(PRStatus) PR_SetPollableEvent(PRFileDesc *event)
111
 
{
112
 
    /*
113
 
    ** Just set the event flag.
114
 
    */
115
 
    unsigned int status;
116
 
    status = sys$setef(-PR_FileDesc2NativeHandle(event));
117
 
    if (!$VMS_STATUS_SUCCESS(status)) {
118
 
        PR_SetError(PR_INVALID_ARGUMENT_ERROR, status);
119
 
        return PR_FAILURE;
120
 
    }
121
 
    return PR_SUCCESS;
122
 
}
123
 
 
124
 
PR_IMPLEMENT(PRStatus) PR_WaitForPollableEvent(PRFileDesc *event)
125
 
{
126
 
    /*
127
 
    ** Just clear the event flag.
128
 
    */
129
 
    unsigned int status;
130
 
    status = sys$clref(-PR_FileDesc2NativeHandle(event));
131
 
    if (!$VMS_STATUS_SUCCESS(status)) {
132
 
        PR_SetError(PR_INVALID_ARGUMENT_ERROR, status);
133
 
        return PR_FAILURE;
134
 
    }
135
 
    return PR_SUCCESS;
136
 
}
137
 
 
138
 
#elif defined (XP_MAC)
139
 
 
140
 
#include "primpl.h"
141
 
 
142
 
/*
143
 
 * On Mac, local sockets cannot be used, because the networking stack
144
 
 * closes them when the machine goes to sleep. Instead, we'll use a simple
145
 
 * flag.
146
 
 */
147
 
 
148
 
 
149
 
/*
150
 
 * PRFilePrivate structure for the NSPR pollable events layer
151
 
 */
152
 
typedef struct PRPollableDesc {
153
 
    PRBool      gotEvent;
154
 
    PRThread    *pollingThread;
155
 
} PRPollableDesc;
156
 
 
157
 
static PRStatus PR_CALLBACK _pr_MacPolEvtClose(PRFileDesc *fd);
158
 
 
159
 
static PRInt16 PR_CALLBACK _pr_MacPolEvtPoll(
160
 
    PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags);
161
 
 
162
 
static PRIOMethods _pr_mac_polevt_methods = {
163
 
    PR_DESC_LAYERED,
164
 
    _pr_MacPolEvtClose,
165
 
    (PRReadFN)_PR_InvalidInt,
166
 
    (PRWriteFN)_PR_InvalidInt,
167
 
    (PRAvailableFN)_PR_InvalidInt,
168
 
    (PRAvailable64FN)_PR_InvalidInt64,
169
 
    (PRFsyncFN)_PR_InvalidStatus,
170
 
    (PRSeekFN)_PR_InvalidInt,
171
 
    (PRSeek64FN)_PR_InvalidInt64,
172
 
    (PRFileInfoFN)_PR_InvalidStatus,
173
 
    (PRFileInfo64FN)_PR_InvalidStatus,
174
 
    (PRWritevFN)_PR_InvalidInt,        
175
 
    (PRConnectFN)_PR_InvalidStatus,        
176
 
    (PRAcceptFN)_PR_InvalidDesc,        
177
 
    (PRBindFN)_PR_InvalidStatus,        
178
 
    (PRListenFN)_PR_InvalidStatus,        
179
 
    (PRShutdownFN)_PR_InvalidStatus,    
180
 
    (PRRecvFN)_PR_InvalidInt,        
181
 
    (PRSendFN)_PR_InvalidInt,        
182
 
    (PRRecvfromFN)_PR_InvalidInt,    
183
 
    (PRSendtoFN)_PR_InvalidInt,        
184
 
    _pr_MacPolEvtPoll,
185
 
    (PRAcceptreadFN)_PR_InvalidInt,   
186
 
    (PRTransmitfileFN)_PR_InvalidInt, 
187
 
    (PRGetsocknameFN)_PR_InvalidStatus,    
188
 
    (PRGetpeernameFN)_PR_InvalidStatus,    
189
 
    (PRReservedFN)_PR_InvalidInt,    
190
 
    (PRReservedFN)_PR_InvalidInt,    
191
 
    (PRGetsocketoptionFN)_PR_InvalidStatus,
192
 
    (PRSetsocketoptionFN)_PR_InvalidStatus,
193
 
    (PRSendfileFN)_PR_InvalidInt, 
194
 
    (PRConnectcontinueFN)_PR_InvalidStatus, 
195
 
    (PRReservedFN)_PR_InvalidInt, 
196
 
    (PRReservedFN)_PR_InvalidInt, 
197
 
    (PRReservedFN)_PR_InvalidInt, 
198
 
    (PRReservedFN)_PR_InvalidInt
199
 
};
200
 
 
201
 
static PRDescIdentity _pr_mac_polevt_id;
202
 
static PRCallOnceType _pr_mac_polevt_once_control;
203
 
static PRStatus PR_CALLBACK _pr_MacPolEvtInit(void);
204
 
 
205
 
static PRInt16 PR_CALLBACK _pr_MacPolEvtPoll(
206
 
    PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags)
207
 
{
208
 
    PRPollableDesc   *pollDesc = (PRPollableDesc *)fd->secret;
209
 
    PR_ASSERT(pollDesc);
210
 
 
211
 
    // set the current thread so that we can wake up the poll thread
212
 
    pollDesc->pollingThread = PR_GetCurrentThread();
213
 
 
214
 
    if ((in_flags & PR_POLL_READ) && pollDesc->gotEvent)
215
 
        *out_flags = PR_POLL_READ;
216
 
    else
217
 
        *out_flags = 0;
218
 
    return pollDesc->gotEvent ? 1 : 0;
219
 
}
220
 
 
221
 
static PRStatus PR_CALLBACK _pr_MacPolEvtInit(void)
222
 
{
223
 
    _pr_mac_polevt_id = PR_GetUniqueIdentity("NSPR pollable events");
224
 
    if (PR_INVALID_IO_LAYER == _pr_mac_polevt_id) {
225
 
        return PR_FAILURE;
226
 
    }
227
 
    return PR_SUCCESS;
228
 
}
229
 
 
230
 
static PRStatus PR_CALLBACK _pr_MacPolEvtClose(PRFileDesc *fd)
231
 
{
232
 
    PRPollableDesc   *pollDesc = (PRPollableDesc *)fd->secret;
233
 
    PR_ASSERT(NULL == fd->higher && NULL == fd->lower);
234
 
    PR_ASSERT(pollDesc);
235
 
    PR_DELETE(pollDesc);
236
 
    fd->dtor(fd);
237
 
    return PR_SUCCESS;
238
 
}
239
 
 
240
 
PR_IMPLEMENT(PRFileDesc *) PR_NewPollableEvent(void)
241
 
{
242
 
    PRFileDesc      *event;
243
 
    PRPollableDesc   *pollDesc;
244
 
    
245
 
    if (PR_CallOnce(&_pr_mac_polevt_once_control, _pr_MacPolEvtInit) == PR_FAILURE) {
246
 
        return NULL;
247
 
    }
248
 
 
249
 
    event = PR_CreateIOLayerStub(_pr_mac_polevt_id, &_pr_mac_polevt_methods);
250
 
    if (NULL == event) {
251
 
        return NULL;
252
 
    } 
253
 
 
254
 
    /*
255
 
    ** Allocate an event flag and clear it.
256
 
    */
257
 
    pollDesc = PR_NEW(PRPollableDesc);
258
 
    if (!pollDesc) {
259
 
        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
260
 
        goto errorExit;
261
 
    }
262
 
 
263
 
    pollDesc->gotEvent = PR_FALSE;
264
 
    pollDesc->pollingThread = NULL;
265
 
    
266
 
    event->secret = (PRFilePrivate*)pollDesc;
267
 
    return event;
268
 
 
269
 
errorExit:
270
 
 
271
 
    if (event) {
272
 
        PR_DELETE(event->secret);
273
 
        event->dtor(event);
274
 
    }
275
 
    return NULL;
276
 
}
277
 
 
278
 
PR_IMPLEMENT(PRStatus) PR_DestroyPollableEvent(PRFileDesc *event)
279
 
{
280
 
    return PR_Close(event);
281
 
}
282
 
 
283
 
/* from macsockotpt.c. I wish there was a cleaner way */
284
 
extern void WakeUpNotifiedThread(PRThread *thread, OTResult result);
285
 
 
286
 
PR_IMPLEMENT(PRStatus) PR_SetPollableEvent(PRFileDesc *event)
287
 
{
288
 
    PRPollableDesc   *pollDesc = (PRPollableDesc *)event->secret;
289
 
    PR_ASSERT(pollDesc);
290
 
    PR_ASSERT(pollDesc->pollingThread->state != _PR_DEAD_STATE);
291
 
    
292
 
    if (pollDesc->pollingThread->state == _PR_DEAD_STATE)
293
 
      return PR_FAILURE;
294
 
 
295
 
    pollDesc->gotEvent = PR_TRUE;
296
 
    
297
 
    if (pollDesc->pollingThread)
298
 
        WakeUpNotifiedThread(pollDesc->pollingThread, noErr);
299
 
        
300
 
    return PR_SUCCESS;
301
 
}
302
 
 
303
 
PR_IMPLEMENT(PRStatus) PR_WaitForPollableEvent(PRFileDesc *event)
304
 
{
305
 
    PRPollableDesc   *pollDesc = (PRPollableDesc *)event->secret;
306
 
    PRStatus status;    
307
 
    PR_ASSERT(pollDesc);
308
 
    
309
 
    /*
310
 
      FIXME: Danger Will Robinson!
311
 
      
312
 
      The current implementation of PR_WaitForPollableEvent is somewhat
313
 
      bogus; it makes the assumption that, in Mozilla, this will only
314
 
      ever be called when PR_Poll has returned, telling us that an
315
 
      event has been set.
316
 
    */
317
 
    
318
 
    PR_ASSERT(pollDesc->gotEvent);
319
 
    
320
 
    status = (pollDesc->gotEvent) ? PR_SUCCESS : PR_FAILURE;
321
 
    pollDesc->gotEvent = PR_FALSE;
322
 
    return status;    
323
 
}
324
 
 
325
 
#else /* VMS */
326
 
 
327
61
/*
328
62
 * These internal functions are declared in primpl.h,
329
63
 * but we can't include primpl.h because the definition
526
260
 
527
261
    return PR_SUCCESS;
528
262
}
529
 
 
530
 
#endif /* VMS */