home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / RCPOPUP.ZIP / ASYNC.C next >
C/C++ Source or Header  |  1992-09-28  |  6KB  |  143 lines

  1.  
  2. /*****************************************************************************/
  3. /*                                                                           */
  4. /*  Function: DosReadAsync / DosWriteAsync                                   */
  5. /*                                                                           */
  6. /*   Creator: Rick Curry, Janus Systems, Inc., 833 Flynn Camarillo, CA 93012 */
  7. /*            (805)484-9770                                                  */
  8. /*                                                                           */
  9. /*   Purpose: When IBM rewrote their API for OS/2 2.0, they decided that     */
  10. /*            the Read/Write Async calls where either unnecessary or         */
  11. /*            undesirable.  The following code implements the Async calls    */
  12. /*            as closely as possible.  The most notable difference is that   */
  13. /*            there are no longer RAM semaphores which is what the old       */
  14. /*            (MicroSoft) functions used to use.  These functions open an    */
  15. /*            anonymous (unnamed) semaphore for you and return the handle    */
  16. /*            so that you can do a DosWaitEventSem (or whatever other Event  */
  17. /*            semaphore functions you like to use.)  The calling function is */
  18. /*            expected to DosCloseEventSem the semaphore.  Also since this   */
  19. /*            function creates a thread to do the actual I/O, it is          */
  20. /*            important that any program which calls this function is built  */
  21. /*            for multi-threaded execution (/Gm+).                           */
  22. /*                                                                           */
  23. /*  To build: icc -c -W3 /Kf-c+e+p+r+ /Q /Gm async.c                         */
  24. /*                                                                           */
  25. /*    To use: See MicroSoft documentation for OS/2 1.2 or 1.3 API with       */
  26. /*            differences noted in Purpose (above.)                          */
  27. /*                                                                           */
  28. /*      File: async.c                                                        */
  29. /*                                                                           */
  30. /*****************************************************************************/
  31.  
  32.  
  33. #define INCL_DOSERRORS
  34. #define INCL_DOSFILEMGR
  35. #define INCL_DOSSEMAPHORES
  36. #include <os2.h>
  37.  
  38. #include <stdlib.h>
  39.  
  40.         /* Packet of parameters for dispatched (engine) part of read/write */
  41. struct AsyncParams {
  42.   HFILE hf;                             /* Handle to open file */
  43.   PHEV pphev;                           /* Pointer to handle for event sem */
  44.   PULONG pulErrCode;                    /* Ptr to completion code for engine */
  45.   PVOID pvBuf;                          /* Buffer to transfer */
  46.   ULONG cbBuf;                          /* Req. # bytes to transfer */
  47.   PULONG pcbBytesActual; };             /* Ptr to var rcvs actual bytes xfer */
  48.  
  49.         /* Dispatched (engine) part of DosReadAsync */
  50. static void RAEngine(void *inp_arg) {
  51.   struct AsyncParams *AP=inp_arg;
  52.   APIRET rc;
  53.  
  54.   rc = DosRead(AP->hf, AP->pvBuf, AP->cbBuf, AP->pcbBytesActual);
  55.   *AP->pulErrCode = rc;                 /* Post completion code */
  56.   DosPostEventSem(*AP->pphev);          /* Release waiter(s) */
  57.   free(AP);                             /* Free parameters packet */
  58. }
  59.  
  60.  
  61.         /* API for modified (CSET/2) version of DosReadAsync */
  62. ULONG DosReadAsync(HFILE hf, PHEV pphev, PULONG pulErrCode, PVOID pvBuf, ULONG cbBuf, PULONG pcbBytesActual) {
  63.   APIRET rc;
  64.   ULONG tid;
  65.   struct AsyncParams *AP;
  66.  
  67.         /* Allocate an AP packet */
  68.   AP = (struct AsyncParams *)malloc(sizeof(*AP));
  69.   if (AP == NULL) return(ERROR_NOT_ENOUGH_MEMORY);
  70.  
  71.   AP->hf              = hf;             /* Fill in the packet */
  72.   AP->pphev           = pphev;
  73.   AP->pulErrCode      = pulErrCode;
  74.   AP->pvBuf           = pvBuf;
  75.   AP->cbBuf           = cbBuf;
  76.   AP->pcbBytesActual  = pcbBytesActual;
  77.  
  78.         /* Create an anonymous event sem to signal IO completion */
  79.   rc = DosCreateEventSem(NULL, pphev, 0, FALSE);
  80.   if (rc != 0) {
  81.     free(AP);
  82.     return(rc);
  83.   }
  84.  
  85.         /* Dispatch work thread (engine) and forget the ID */
  86.   tid = _beginthread(RAEngine, NULL, 4*4096, (void *)AP);
  87.   if (tid == -1) {
  88.     free(AP);
  89.     DosCloseEventSem(*pphev);
  90.     return(ERROR_MAX_THRDS_REACHED);
  91.   }
  92.  
  93.   return(NO_ERROR);
  94. }
  95.  
  96.  
  97.         /* Dispatched (engine) part of DosWriteAsync */
  98. static void WAEngine(void *inp_arg) {
  99.   struct AsyncParams *AP=inp_arg;
  100.   APIRET rc;
  101.  
  102.   rc = DosWrite(AP->hf, AP->pvBuf, AP->cbBuf, AP->pcbBytesActual);
  103.   *AP->pulErrCode = rc;                 /* Post completion code */
  104.   DosPostEventSem(*AP->pphev);          /* Release waiter(s) */
  105.   free(AP);                             /* Free parameters packet */
  106. }
  107.  
  108.  
  109.         /* API for modified (CSET/2) version of DosWriteAsync */
  110. ULONG DosWriteAsync(HFILE hf, PHEV pphev, PULONG pulErrCode, PVOID pvBuf, ULONG cbBuf, PULONG pcbBytesActual) {
  111.   APIRET rc;
  112.   ULONG tid;
  113.   struct AsyncParams *AP;
  114.  
  115.         /* Allocate an AP packet */
  116.   AP = (struct AsyncParams *)malloc(sizeof(*AP));
  117.   if (AP == NULL) return(ERROR_NOT_ENOUGH_MEMORY);
  118.  
  119.   AP->hf              = hf;             /* Fill in the packet */
  120.   AP->pphev           = pphev;
  121.   AP->pulErrCode      = pulErrCode;
  122.   AP->pvBuf           = pvBuf;
  123.   AP->cbBuf           = cbBuf;
  124.   AP->pcbBytesActual  = pcbBytesActual;
  125.  
  126.         /* Create an anonymous event sem to signal IO completion */
  127.   rc = DosCreateEventSem(NULL, pphev, 0, FALSE);
  128.   if (rc != 0) {
  129.     free(AP);
  130.     return(rc);
  131.   }
  132.  
  133.         /* Dispatch work thread (engine) and forget the ID */
  134.   tid = _beginthread(WAEngine, NULL, 4*4096, (void *)AP);
  135.   if (tid == -1) {
  136.     free(AP);
  137.     DosCloseEventSem(*pphev);
  138.     return(ERROR_MAX_THRDS_REACHED);
  139.   }
  140.  
  141.   return(NO_ERROR);
  142. }
  143.