Back to index

lightning-sunbird  0.9+nobinonly
intrio.c
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is the Netscape Portable Runtime (NSPR).
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 2000
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either the GNU General Public License Version 2 or later (the "GPL"), or
00026  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 /*
00039  * File:        intrio.c
00040  * Purpose:     testing i/o interrupts (see Bugzilla bug #31120)
00041  */
00042 
00043 #include "nspr.h"
00044 
00045 #include <stdio.h>
00046 #include <stdlib.h>
00047 #include <string.h>
00048 
00049 #ifdef XP_MAC
00050 #include "prlog.h"
00051 #define printf PR_LogPrint
00052 extern void SetupMacPrintfLog(char *logFile);
00053 #endif
00054 
00055 /* for synchronization between the main thread and iothread */
00056 static PRLock *lock;
00057 static PRCondVar *cvar;
00058 static PRBool iothread_ready;
00059 
00060 static void PR_CALLBACK AbortIO(void *arg)
00061 {
00062     PRStatus rv;
00063     PR_Sleep(PR_SecondsToInterval(2));
00064     rv = PR_Interrupt((PRThread*)arg);
00065     PR_ASSERT(PR_SUCCESS == rv);
00066 }  /* AbortIO */
00067 
00068 static void PR_CALLBACK IOThread(void *arg)
00069 {
00070     PRFileDesc *sock, *newsock;
00071     PRNetAddr addr;
00072 
00073     sock = PR_OpenTCPSocket(PR_AF_INET6);
00074     if (sock == NULL) {
00075         fprintf(stderr, "PR_OpenTCPSocket failed\n");
00076         exit(1);
00077     }
00078     memset(&addr, 0, sizeof(addr));
00079     if (PR_SetNetAddr(PR_IpAddrAny, PR_AF_INET6, 0, &addr) == PR_FAILURE) {
00080         fprintf(stderr, "PR_SetNetAddr failed\n");
00081         exit(1);
00082     }
00083     if (PR_Bind(sock, &addr) == PR_FAILURE) {
00084         fprintf(stderr, "PR_Bind failed\n");
00085         exit(1);
00086     }
00087     if (PR_Listen(sock, 5) == PR_FAILURE) {
00088         fprintf(stderr, "PR_Listen failed\n");
00089         exit(1);
00090     }
00091     /* tell the main thread that we are ready */
00092     PR_Lock(lock);
00093     iothread_ready = PR_TRUE;
00094     PR_NotifyCondVar(cvar);
00095     PR_Unlock(lock);
00096     newsock = PR_Accept(sock, NULL, PR_INTERVAL_NO_TIMEOUT);
00097     if (newsock != NULL) {
00098         fprintf(stderr, "PR_Accept shouldn't have succeeded\n");
00099         exit(1);
00100     }
00101     if (PR_GetError() != PR_PENDING_INTERRUPT_ERROR) {
00102         fprintf(stderr, "PR_Accept failed (%d, %d)\n",
00103             PR_GetError(), PR_GetOSError());
00104         exit(1);
00105     }
00106     printf("PR_Accept() is interrupted as expected\n");
00107     if (PR_Close(sock) == PR_FAILURE) {
00108         fprintf(stderr, "PR_Close failed\n");
00109         exit(1);
00110     }
00111 }
00112 
00113 static void Test(PRThreadScope scope1, PRThreadScope scope2)
00114 {
00115     PRThread *iothread, *abortio;
00116 
00117     printf("A %s thread will be interrupted by a %s thread\n",
00118         (scope1 == PR_LOCAL_THREAD ? "local" : "global"),
00119         (scope2 == PR_LOCAL_THREAD ? "local" : "global"));
00120     iothread_ready = PR_FALSE;
00121     iothread = PR_CreateThread(
00122         PR_USER_THREAD, IOThread, NULL, PR_PRIORITY_NORMAL,
00123         scope1, PR_JOINABLE_THREAD, 0);
00124     if (iothread == NULL) {
00125         fprintf(stderr, "cannot create thread\n");
00126         exit(1);
00127     }
00128     PR_Lock(lock);
00129     while (!iothread_ready)
00130         PR_WaitCondVar(cvar, PR_INTERVAL_NO_TIMEOUT);
00131     PR_Unlock(lock);
00132     abortio = PR_CreateThread(
00133         PR_USER_THREAD, AbortIO, iothread, PR_PRIORITY_NORMAL,
00134         scope2, PR_JOINABLE_THREAD, 0);
00135     if (abortio == NULL) {
00136         fprintf(stderr, "cannot create thread\n");
00137         exit(1);
00138     }
00139     if (PR_JoinThread(iothread) == PR_FAILURE) {
00140         fprintf(stderr, "PR_JoinThread failed\n");
00141         exit(1);
00142     }
00143     if (PR_JoinThread(abortio) == PR_FAILURE) {
00144         fprintf(stderr, "PR_JoinThread failed\n");
00145         exit(1);
00146     }
00147 }
00148 
00149 PRIntn main(PRIntn argc, char **argv)
00150 {
00151     PR_STDIO_INIT();
00152     lock = PR_NewLock();
00153     if (lock == NULL) {
00154         fprintf(stderr, "PR_NewLock failed\n");
00155         exit(1);
00156     }
00157     cvar = PR_NewCondVar(lock);
00158     if (cvar == NULL) {
00159         fprintf(stderr, "PR_NewCondVar failed\n");
00160         exit(1);
00161     }
00162     /* test all four combinations */
00163     Test(PR_LOCAL_THREAD, PR_LOCAL_THREAD);
00164     Test(PR_LOCAL_THREAD, PR_GLOBAL_THREAD);
00165     Test(PR_GLOBAL_THREAD, PR_LOCAL_THREAD);
00166     Test(PR_GLOBAL_THREAD, PR_GLOBAL_THREAD);
00167     printf("PASSED\n");
00168     return 0;
00169 }  /* main */