VirtualBox

source: vbox/trunk/src/libs/xpcom18a4/nsprpub/pr/tests/intrupt.c@ 1

Last change on this file since 1 was 1, checked in by vboxsync, 55 years ago

import

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.4 KB
Line 
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2/* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 *
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
9 *
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
14 *
15 * The Original Code is the Netscape Portable Runtime (NSPR).
16 *
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1998-2000
20 * the Initial Developer. All Rights Reserved.
21 *
22 * Contributor(s):
23 *
24 * Alternatively, the contents of this file may be used under the terms of
25 * either the GNU General Public License Version 2 or later (the "GPL"), or
26 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
35 *
36 * ***** END LICENSE BLOCK ***** */
37
38/*
39 * File: intrupt.c
40 * Purpose: testing thread interrupts
41 */
42
43#include "plgetopt.h"
44#include "prcvar.h"
45#include "prerror.h"
46#include "prinit.h"
47#include "prinrval.h"
48#include "prio.h"
49#include "prlock.h"
50#include "prlog.h"
51#include "prthread.h"
52#include "prtypes.h"
53#include "prnetdb.h"
54
55#include <stdio.h>
56#include <string.h>
57
58#ifdef XP_MAC
59#include "prlog.h"
60#define printf PR_LogPrint
61extern void SetupMacPrintfLog(char *logFile);
62#endif
63
64#define DEFAULT_TCP_PORT 12500
65
66static PRLock *ml = NULL;
67static PRCondVar *cv = NULL;
68
69static PRBool passed = PR_TRUE;
70static PRBool debug_mode = PR_FALSE;
71static PRThreadScope thread_scope = PR_LOCAL_THREAD;
72
73static void PR_CALLBACK AbortCV(void *arg)
74{
75 PRStatus rv;
76 PRThread *me = PR_CurrentThread();
77
78 /* some other thread (main) is doing the interrupt */
79 PR_Lock(ml);
80 rv = PR_WaitCondVar(cv, PR_INTERVAL_NO_TIMEOUT);
81 if (debug_mode) printf( "Expected interrupt on wait CV and ");
82 if (PR_FAILURE == rv)
83 {
84 if (PR_PENDING_INTERRUPT_ERROR == PR_GetError())
85 {
86 if (debug_mode) printf("got it\n");
87 }
88 else
89 {
90 if (debug_mode) printf("got random error\n");
91 passed = PR_FALSE;
92 }
93 }
94 else
95 {
96 if (debug_mode) printf("got a successful completion\n");
97 passed = PR_FALSE;
98 }
99
100 rv = PR_WaitCondVar(cv, 10);
101 if (debug_mode)
102 {
103 printf(
104 "Expected success on wait CV and %s\n",
105 (PR_SUCCESS == rv) ? "got it" : "failed");
106 }
107 passed = ((PR_TRUE == passed) && (PR_SUCCESS == rv)) ? PR_TRUE : PR_FALSE;
108
109 /* interrupt myself, then clear */
110 PR_Interrupt(me);
111 PR_ClearInterrupt();
112 rv = PR_WaitCondVar(cv, 10);
113 if (debug_mode)
114 {
115 printf("Expected success on wait CV and ");
116 if (PR_FAILURE == rv)
117 {
118 printf(
119 "%s\n", (PR_PENDING_INTERRUPT_ERROR == PR_GetError()) ?
120 "got interrupted" : "a random failure");
121 }
122 printf("got it\n");
123 }
124 passed = ((PR_TRUE == passed) && (PR_SUCCESS == rv)) ? PR_TRUE : PR_FALSE;
125
126 /* set, then wait - interrupt - then wait again */
127 PR_Interrupt(me);
128 rv = PR_WaitCondVar(cv, 10);
129 if (debug_mode) printf( "Expected interrupt on wait CV and ");
130 if (PR_FAILURE == rv)
131 {
132 if (PR_PENDING_INTERRUPT_ERROR == PR_GetError())
133 {
134 if (debug_mode) printf("got it\n");
135 }
136 else
137 {
138 if (debug_mode) printf("failed\n");
139 passed = PR_FALSE;
140 }
141 }
142 else
143 {
144 if (debug_mode) printf("got a successful completion\n");
145 passed = PR_FALSE;
146 }
147
148 rv = PR_WaitCondVar(cv, 10);
149 if (debug_mode)
150 {
151 printf(
152 "Expected success on wait CV and %s\n",
153 (PR_SUCCESS == rv) ? "got it" : "failed");
154 }
155 passed = ((PR_TRUE == passed) && (PR_SUCCESS == rv)) ? PR_TRUE : PR_FALSE;
156
157 PR_Unlock(ml);
158
159} /* AbortCV */
160
161static void PR_CALLBACK AbortIO(void *arg)
162{
163 PRStatus rv;
164 PR_Sleep(PR_SecondsToInterval(2));
165 rv = PR_Interrupt((PRThread*)arg);
166 PR_ASSERT(PR_SUCCESS == rv);
167} /* AbortIO */
168
169static void PR_CALLBACK AbortJoin(void *arg)
170{
171} /* AbortJoin */
172
173static void setup_listen_socket(PRFileDesc **listner, PRNetAddr *netaddr)
174{
175 PRStatus rv;
176 PRInt16 port = DEFAULT_TCP_PORT;
177
178 *listner = PR_NewTCPSocket();
179 PR_ASSERT(*listner != NULL);
180 memset(netaddr, 0, sizeof(*netaddr));
181 (*netaddr).inet.ip = PR_htonl(PR_INADDR_ANY);
182 (*netaddr).inet.family = PR_AF_INET;
183 do
184 {
185 (*netaddr).inet.port = PR_htons(port);
186 rv = PR_Bind(*listner, netaddr);
187 port += 1;
188 PR_ASSERT(port < (DEFAULT_TCP_PORT + 10));
189 } while (PR_FAILURE == rv);
190
191 rv = PR_Listen(*listner, 5);
192
193 if (PR_GetSockName(*listner, netaddr) < 0) {
194 if (debug_mode) printf("intrupt: ERROR - PR_GetSockName failed\n");
195 passed = PR_FALSE;
196 return;
197 }
198
199}
200
201static void PR_CALLBACK IntrBlock(void *arg)
202{
203 PRStatus rv;
204 PRNetAddr netaddr;
205 PRFileDesc *listner;
206
207 /* some other thread (main) is doing the interrupt */
208 /* block the interrupt */
209 PR_BlockInterrupt();
210 PR_Lock(ml);
211 rv = PR_WaitCondVar(cv, PR_SecondsToInterval(4));
212 PR_Unlock(ml);
213 if (debug_mode)
214 {
215 printf("Expected success on wait CV and ");
216 if (PR_FAILURE == rv)
217 {
218 printf(
219 "%s\n", (PR_PENDING_INTERRUPT_ERROR == PR_GetError()) ?
220 "got interrupted" : "got a random failure");
221 } else
222 printf("got it\n");
223 }
224 passed = ((PR_TRUE == passed) && (PR_SUCCESS == rv)) ? PR_TRUE : PR_FALSE;
225
226 setup_listen_socket(&listner, &netaddr);
227 PR_UnblockInterrupt();
228 if (PR_Accept(listner, &netaddr, PR_INTERVAL_NO_TIMEOUT) == NULL)
229 {
230 PRInt32 error = PR_GetError();
231 if (debug_mode) printf("Expected interrupt on PR_Accept() and ");
232 if (PR_PENDING_INTERRUPT_ERROR == error)
233 {
234 if (debug_mode) printf("got it\n");
235 }
236 else
237 {
238 if (debug_mode) printf("failed\n");
239 passed = PR_FALSE;
240 }
241 }
242 else
243 {
244 if (debug_mode) printf("Failed to interrupt PR_Accept()\n");
245 passed = PR_FALSE;
246 }
247
248 (void)PR_Close(listner); listner = NULL;
249} /* TestIntrBlock */
250
251void PR_CALLBACK Intrupt(void *arg)
252{
253 PRStatus rv;
254 PRNetAddr netaddr;
255 PRFileDesc *listner;
256 PRThread *abortCV, *abortIO, *abortJoin, *intrBlock;
257
258 ml = PR_NewLock();
259 cv = PR_NewCondVar(ml);
260
261#ifdef XP_MAC
262 SetupMacPrintfLog("intrupt.log");
263 debug_mode = PR_TRUE;
264#endif
265
266 /* Part I */
267 if (debug_mode) printf("Part I\n");
268 abortCV = PR_CreateThread(
269 PR_USER_THREAD, AbortCV, 0, PR_PRIORITY_NORMAL,
270 thread_scope, PR_JOINABLE_THREAD, 0);
271
272 PR_Sleep(PR_SecondsToInterval(2));
273 rv = PR_Interrupt(abortCV);
274 PR_ASSERT(PR_SUCCESS == rv);
275 rv = PR_JoinThread(abortCV);
276 PR_ASSERT(PR_SUCCESS == rv);
277
278 /* Part II */
279 if (debug_mode) printf("Part II\n");
280 abortJoin = PR_CreateThread(
281 PR_USER_THREAD, AbortJoin, 0, PR_PRIORITY_NORMAL,
282 thread_scope, PR_JOINABLE_THREAD, 0);
283 PR_Sleep(PR_SecondsToInterval(2));
284 if (debug_mode) printf("Expecting to interrupt an exited thread ");
285 rv = PR_Interrupt(abortJoin);
286 PR_ASSERT(PR_SUCCESS == rv);
287 rv = PR_JoinThread(abortJoin);
288 PR_ASSERT(PR_SUCCESS == rv);
289 if (debug_mode) printf("and succeeded\n");
290
291 /* Part III */
292 if (debug_mode) printf("Part III\n");
293 setup_listen_socket(&listner, &netaddr);
294 abortIO = PR_CreateThread(
295 PR_USER_THREAD, AbortIO, PR_CurrentThread(), PR_PRIORITY_NORMAL,
296 thread_scope, PR_JOINABLE_THREAD, 0);
297
298 if (PR_Accept(listner, &netaddr, PR_INTERVAL_NO_TIMEOUT) == NULL)
299 {
300 PRInt32 error = PR_GetError();
301 if (debug_mode) printf("Expected interrupt on PR_Accept() and ");
302 if (PR_PENDING_INTERRUPT_ERROR == error)
303 {
304 if (debug_mode) printf("got it\n");
305 }
306 else
307 {
308 if (debug_mode) printf("failed\n");
309 passed = PR_FALSE;
310 }
311 }
312 else
313 {
314 if (debug_mode) printf("Failed to interrupt PR_Accept()\n");
315 passed = PR_FALSE;
316 }
317
318 (void)PR_Close(listner); listner = NULL;
319
320 rv = PR_JoinThread(abortIO);
321 PR_ASSERT(PR_SUCCESS == rv);
322 /* Part VI */
323 if (debug_mode) printf("Part VI\n");
324 intrBlock = PR_CreateThread(
325 PR_USER_THREAD, IntrBlock, 0, PR_PRIORITY_NORMAL,
326 thread_scope, PR_JOINABLE_THREAD, 0);
327
328 PR_Sleep(PR_SecondsToInterval(2));
329 rv = PR_Interrupt(intrBlock);
330 PR_ASSERT(PR_SUCCESS == rv);
331 rv = PR_JoinThread(intrBlock);
332 PR_ASSERT(PR_SUCCESS == rv);
333
334 PR_DestroyCondVar(cv);
335 PR_DestroyLock(ml);
336} /* Intrupt */
337
338PRIntn main(PRIntn argc, char **argv)
339{
340 PRThread *intrupt;
341 PLOptStatus os;
342 PLOptState *opt = PL_CreateOptState(argc, argv, "dG");
343 while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
344 {
345 if (PL_OPT_BAD == os) continue;
346 switch (opt->option)
347 {
348 case 'd': /* debug mode */
349 debug_mode = PR_TRUE;
350 break;
351 case 'G': /* use global threads */
352 thread_scope = PR_GLOBAL_THREAD;
353 break;
354 }
355 }
356 PL_DestroyOptState(opt);
357 PR_STDIO_INIT();
358 intrupt = PR_CreateThread(
359 PR_USER_THREAD, Intrupt, NULL, PR_PRIORITY_NORMAL,
360 thread_scope, PR_JOINABLE_THREAD, 0);
361 if (intrupt == NULL) {
362 fprintf(stderr, "cannot create thread\n");
363 passed = PR_FALSE;
364 } else {
365 PRStatus rv;
366 rv = PR_JoinThread(intrupt);
367 PR_ASSERT(rv == PR_SUCCESS);
368 }
369 printf("%s\n", ((passed) ? "PASSED" : "FAILED"));
370 return ((passed) ? 0 : 1);
371} /* main */
372
373/* intrupt.c */
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette