home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / nsprpub / pr / src / io / prio.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  5.4 KB  |  185 lines

  1. /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /*
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  * 
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  * 
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18.  
  19. #include "primpl.h"
  20.  
  21. #include <string.h> /* for memset() */
  22.  
  23.  
  24. /************************************************************************/
  25.  
  26. PRLock *_pr_flock_lock;
  27.  
  28. PRFileDesc *_pr_filedesc_freelist;
  29. PRLock *_pr_filedesc_freelist_lock;
  30.  
  31. void _PR_InitIO(void)
  32. {
  33.     PRIOMethods *methods = PR_GetFileMethods();
  34.  
  35.     _pr_filedesc_freelist = NULL;
  36.     _pr_filedesc_freelist_lock = PR_NewLock();
  37.     _pr_flock_lock = PR_NewLock();
  38.  
  39. #ifdef WIN32
  40.     _pr_stdin = PR_AllocFileDesc((PRInt32)GetStdHandle(STD_INPUT_HANDLE),
  41.             methods);
  42.     _pr_stdout = PR_AllocFileDesc((PRInt32)GetStdHandle(STD_OUTPUT_HANDLE),
  43.             methods);
  44.     _pr_stderr = PR_AllocFileDesc((PRInt32)GetStdHandle(STD_ERROR_HANDLE),
  45.             methods);
  46. #ifdef WINNT
  47.     _pr_stdin->secret->md.nonoverlapped = PR_TRUE;
  48.     _pr_stdout->secret->md.nonoverlapped = PR_TRUE;
  49.     _pr_stderr->secret->md.nonoverlapped = PR_TRUE;
  50. #endif
  51. #else
  52.     _pr_stdin = PR_AllocFileDesc(0, methods);
  53.     _pr_stdout = PR_AllocFileDesc(1, methods);
  54.     _pr_stderr = PR_AllocFileDesc(2, methods);
  55. #endif
  56.  
  57.     _PR_MD_INIT_IO();
  58. }
  59.  
  60. PR_IMPLEMENT(PRFileDesc*) PR_GetSpecialFD(PRSpecialFD osfd)
  61. {
  62.     PRFileDesc *result = NULL;
  63.     PR_ASSERT(osfd >= PR_StandardInput && osfd <= PR_StandardError);
  64.  
  65.     if (!_pr_initialized) _PR_ImplicitInitialization();
  66.     
  67.     switch (osfd)
  68.     {
  69.         case PR_StandardInput: result = _pr_stdin; break;
  70.         case PR_StandardOutput: result = _pr_stdout; break;
  71.         case PR_StandardError: result = _pr_stderr; break;
  72.         default:
  73.             (void)PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
  74.     }
  75.     return result;
  76. }
  77.  
  78. PR_IMPLEMENT(PRFileDesc*) PR_AllocFileDesc(PRInt32 osfd, PRIOMethods *methods)
  79. {
  80.     PRFileDesc *fd;
  81.  
  82. #ifdef XP_UNIX
  83.     /*
  84.      * Assert that the file descriptor is small enough to fit in the
  85.      * fd_set passed to select
  86.      */
  87.     PR_ASSERT(osfd < FD_SETSIZE);
  88. #endif
  89.     if (_pr_filedesc_freelist) {
  90.         PR_Lock(_pr_filedesc_freelist_lock);
  91.         if (_pr_filedesc_freelist) {
  92.             PRFilePrivate *secretSave;
  93.             fd = _pr_filedesc_freelist;
  94.             _pr_filedesc_freelist = _pr_filedesc_freelist->secret->next;
  95.             PR_Unlock(_pr_filedesc_freelist_lock);
  96.             secretSave = fd->secret;
  97.             memset(fd, 0, sizeof(PRFileDesc));
  98.             memset(secretSave, 0, sizeof(PRFilePrivate));
  99.             fd->secret = secretSave;
  100.         } else {
  101.             PR_Unlock(_pr_filedesc_freelist_lock);
  102.             fd = PR_NEWZAP(PRFileDesc);
  103.             fd->secret = PR_NEWZAP(PRFilePrivate);
  104.         }
  105.     } else {
  106.         fd = PR_NEWZAP(PRFileDesc);
  107.         fd->secret = PR_NEWZAP(PRFilePrivate);
  108.     }
  109.     if (fd) {
  110.         /* Initialize the members of PRFileDesc and PRFilePrivate */
  111.         fd->methods = methods;
  112.         fd->secret->state = _PR_FILEDESC_OPEN;
  113.     fd->secret->md.osfd = osfd;
  114.     } else {
  115.         PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
  116.     }
  117.  
  118.     return fd;
  119. }
  120.  
  121. PR_IMPLEMENT(void) PR_FreeFileDesc(PRFileDesc *fd)
  122. {
  123.     PR_ASSERT(fd);
  124.     PR_ASSERT(fd->secret->state == _PR_FILEDESC_CLOSED);
  125.  
  126.     fd->secret->state = _PR_FILEDESC_FREED;
  127.  
  128.     PR_Lock(_pr_filedesc_freelist_lock);
  129.  
  130.     /* Add to head of list- this is a LIFO structure to avoid constantly
  131.      * using different structs
  132.      */
  133.     fd->secret->next = _pr_filedesc_freelist;
  134.     _pr_filedesc_freelist = fd;
  135.  
  136.     PR_Unlock(_pr_filedesc_freelist_lock);
  137. }
  138.  
  139. #ifdef XP_UNIX
  140. #include <fcntl.h>    /* to pick up F_GETFL */
  141. #endif
  142.  
  143. /*
  144. ** Wait for some i/o to finish on one or more more poll descriptors.
  145. */
  146. PR_IMPLEMENT(PRInt32) PR_Poll(PRPollDesc *pds, PRIntn npds,
  147.     PRIntervalTime timeout)
  148. {
  149.     PRPollDesc *pd, *epd;
  150.     PRInt32 n;
  151.     PRThread *me = _PR_MD_CURRENT_THREAD();
  152.  
  153.     if (_PR_PENDING_INTERRUPT(me)) {
  154.         me->flags &= ~_PR_INTERRUPT;
  155.         PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
  156.         return -1;
  157.     }
  158.     /*
  159.     ** Before we do the poll operation, check each descriptor and see if
  160.     ** it needs special poll handling. If it does, use the method poll
  161.     ** proc to check for data before blocking.
  162.     */
  163.     pd = pds;
  164.     n = 0;
  165.     for (pd = pds, epd = pd + npds; pd < epd; pd++) {
  166.         PRFileDesc *fd = pd->fd;
  167.         PRInt16 in_flags;
  168.         if (NULL == fd) {
  169.             continue;
  170.         }
  171.         in_flags = pd->in_flags;
  172.         if (in_flags && fd->methods->poll) {
  173.             PRInt16 out_flags = (*fd->methods->poll)(fd, in_flags);
  174.             if (out_flags) {
  175.                 pd->out_flags = out_flags;
  176.                 n++;
  177.             }
  178.         }
  179.     }
  180.     if (n != 0) {
  181.         return n;
  182.     }
  183.     return(_PR_MD_PR_POLL(pds, npds, timeout));
  184. }
  185.