Back to index

lightning-sunbird  0.9+nobinonly
fileio.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) 1998-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 **
00040 ** Name: fileio.c
00041 **
00042 ** Description: Program to copy one file to another. 
00043 **
00044 ** Modification History:
00045 ** 14-May-97 AGarcia- Converted the test to accomodate the debug_mode flag.
00046 **              The debug mode will print all of the printfs associated with this test.
00047 **                    The regress mode will be the default mode. Since the regress tool limits
00048 **           the output to a one line status:PASS or FAIL,all of the printf statements
00049 **                    have been handled with an if (debug_mode) statement.
00050 ** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to
00051 **                   recognize the return code from tha main program.
00052 ** 12-June-97 Revert to return code 0 and 1, remove debug option (obsolete).
00053 ***********************************************************************/
00054 
00055 /***********************************************************************
00056 ** Includes
00057 ***********************************************************************/
00058 #include "prinit.h"
00059 #include "prthread.h"
00060 #include "prlock.h"
00061 #include "prcvar.h"
00062 #include "prmon.h"
00063 #include "prmem.h"
00064 #include "prio.h"
00065 #include "prlog.h"
00066 
00067 #include <stdio.h>
00068 
00069 #ifdef XP_MAC
00070 #include "prsem.h"
00071 #include "prlog.h"
00072 #define printf PR_LogPrint
00073 extern void SetupMacPrintfLog(char *logFile);
00074 #else
00075 #include "obsolete/prsem.h"
00076 #endif
00077 
00078 
00079 #define TBSIZE 1024
00080 
00081 static PRUint8 tbuf[TBSIZE];
00082 
00083 static PRFileDesc *t1, *t2;
00084 
00085 PRIntn failed_already=0;
00086 PRIntn debug_mode;
00087 static void InitialSetup(void)
00088 {
00089        PRUintn       i;
00090        PRInt32 nWritten, rv;
00091        
00092        t1 = PR_Open("t1.tmp", PR_CREATE_FILE | PR_RDWR, 0);
00093        PR_ASSERT(t1 != NULL);      
00094        
00095        for (i=0; i<TBSIZE; i++)
00096               tbuf[i] = i;
00097               
00098        nWritten = PR_Write((PRFileDesc*)t1, tbuf, TBSIZE);
00099        PR_ASSERT(nWritten == TBSIZE);     
00100               
00101        rv = PR_Seek(t1,0,PR_SEEK_SET);
00102        PR_ASSERT(rv == 0);  
00103 
00104        t2 = PR_Open("t2.tmp", PR_CREATE_FILE | PR_RDWR, 0);
00105        PR_ASSERT(t2 != NULL);      
00106 }
00107 
00108 
00109 static void VerifyAndCleanup(void)
00110 {
00111        PRUintn       i;
00112        PRInt32 nRead, rv;
00113        
00114        for (i=0; i<TBSIZE; i++)
00115               tbuf[i] = 0;
00116               
00117        rv = PR_Seek(t2,0,PR_SEEK_SET);
00118        PR_ASSERT(rv == 0);  
00119 
00120        nRead = PR_Read((PRFileDesc*)t2, tbuf, TBSIZE);
00121        PR_ASSERT(nRead == TBSIZE); 
00122               
00123        for (i=0; i<TBSIZE; i++)
00124               if (tbuf[i] != (PRUint8)i) {
00125                      if (debug_mode) printf("data mismatch for index= %d \n", i);
00126                      else failed_already=1;
00127               }
00128        PR_Close(t1);
00129        PR_Close(t2);
00130 
00131        PR_Delete("t1.tmp");
00132        PR_Delete("t2.tmp");
00133 
00134     if (debug_mode) printf("fileio test passed\n");
00135 }
00136 
00137 
00138 /*------------------ Following is the real test program ---------*/
00139 /*
00140        Program to copy one file to another.  Two temporary files get
00141        created.  First one gets written in one write call.  Then,
00142        a reader thread reads from this file into a double buffer.
00143        The writer thread writes from double buffer into the other
00144        temporary file.  The second temporary file gets verified
00145        for accurate data.
00146 */
00147 
00148 PRSemaphore   *emptyBufs;   /* number of empty buffers */
00149 PRSemaphore *fullBufs;      /* number of buffers that are full */
00150 
00151 #define BSIZE 100
00152 
00153 struct {
00154        char data[BSIZE];
00155        PRUintn nbytes;             /* number of bytes in this buffer */
00156 } buf[2];
00157 
00158 static void PR_CALLBACK reader(void *arg)
00159 {
00160        PRUintn       i = 0;
00161        PRInt32       nbytes;
00162        
00163        do {
00164               (void) PR_WaitSem(emptyBufs);
00165               nbytes = PR_Read((PRFileDesc*)arg, buf[i].data, BSIZE);
00166               if (nbytes >= 0) {
00167                      buf[i].nbytes = nbytes;
00168                      PR_PostSem(fullBufs);
00169                      i = (i + 1) % 2;
00170               }
00171        } while (nbytes > 0);
00172 }
00173 
00174 static void PR_CALLBACK writer(void *arg)
00175 {
00176        PRUintn       i = 0;
00177        PRInt32       nbytes;
00178        
00179        do {
00180               (void) PR_WaitSem(fullBufs);
00181               nbytes = buf[i].nbytes;
00182               if (nbytes > 0) {
00183                      nbytes = PR_Write((PRFileDesc*)arg, buf[i].data, nbytes);
00184                      PR_PostSem(emptyBufs);
00185                      i = (i + 1) % 2;
00186               }
00187        } while (nbytes > 0);
00188 }
00189 
00190 int main(int argc, char **argv)
00191 {
00192        PRThread *r, *w;
00193 
00194 
00195        PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
00196     PR_STDIO_INIT();
00197 
00198 #ifdef XP_MAC
00199        SetupMacPrintfLog("fileio.log");
00200        debug_mode = 1;
00201 #endif
00202 
00203     emptyBufs = PR_NewSem(2);      /* two empty buffers */
00204 
00205     fullBufs = PR_NewSem(0);       /* zero full buffers */
00206 
00207        /* Create initial temp file setup */
00208        InitialSetup();
00209        
00210        /* create the reader thread */
00211        
00212        r = PR_CreateThread(PR_USER_THREAD,
00213                                   reader, t1, 
00214                                   PR_PRIORITY_NORMAL,
00215                                   PR_LOCAL_THREAD,
00216                               PR_JOINABLE_THREAD,
00217                                   0);
00218 
00219        w = PR_CreateThread(PR_USER_THREAD,
00220                                   writer, t2, 
00221                                   PR_PRIORITY_NORMAL,
00222                       PR_LOCAL_THREAD,
00223                       PR_JOINABLE_THREAD,
00224                       0);
00225 
00226     /* Do the joining for both threads */
00227     (void) PR_JoinThread(r);
00228     (void) PR_JoinThread(w);
00229 
00230     /* Do the verification and clean up */
00231     VerifyAndCleanup();
00232 
00233     PR_DestroySem(emptyBufs);
00234     PR_DestroySem(fullBufs);
00235 
00236     PR_Cleanup();
00237 
00238     if(failed_already)
00239     {
00240         printf("Fail\n");
00241         return 1;
00242     }
00243     else
00244     {
00245         printf("PASS\n");
00246         return 0;
00247     }
00248 
00249 
00250 }