home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / octa21fs.zip / octave / mkfifo / nmp_thread.c < prev    next >
C/C++ Source or Header  |  2000-01-15  |  5KB  |  191 lines

  1. /*
  2. ** ****************************************************************************
  3. ** Thread for exchanging the data. This routine is started by the server in
  4. ** new thread for every nmaed pipe.
  5. ** (c) Klaus Gebhardt, 1997
  6. ** ****************************************************************************
  7. */
  8.  
  9. /*
  10. ** ****************************************************************************
  11. ** This is part of the server the mkfifo command connects to. This program
  12. ** creates a named pipe which is used for communication between the mkfifo
  13. ** routine and the server. The mkfifo sends the name of the named pipe,
  14. ** which should be created and then receives the return code.
  15. ** (c) Klaus Gebhardt, 1997
  16. ** ****************************************************************************
  17. */
  18.  
  19. /*
  20. ** ****************************************************************************
  21. ** This was written for the OS/2 port of Octave, but it is not part of Octave!
  22. ** You can use the code UNMODIFIED. If you think changes are necessary,
  23. ** please send me a mail (gebhardt@crunch.ikp.physik.th-darmstadt.de).
  24. ** Thanks,
  25. **   Klaus Gebhardt
  26. ** ****************************************************************************
  27. */
  28.  
  29. #include "nmp.h"
  30.  
  31. /*
  32. ** This function creates a named pipe and connects to it. The function
  33. ** returns 0 on success, -1 on error.
  34. */
  35. static int create_npipe (const char *name, HPIPE *hpipe)
  36. {
  37.   APIRET apiret;
  38.  
  39.   apiret = DosCreateNPipe (name, hpipe, NP_ACCESS_DUPLEX,
  40.                            NP_NOWAIT | NP_TYPE_BYTE | NP_READMODE_BYTE |
  41.                            0xFF, 1024L, 1024L, -1);
  42.  
  43.   if (apiret)  return -1;
  44.  
  45.   apiret = DosConnectNPipe (*hpipe);
  46.   if (apiret && (apiret != 233))  return -1;
  47.  
  48.   apiret = DosSetNPHState (*hpipe, NP_WAIT);
  49.   if (apiret && (apiret != 233))  return -1;
  50.  
  51.   return 0;
  52. }
  53.  
  54.  
  55. /*
  56. ** This routine disconnects from a named pipe and closes the named pipe.
  57. ** It returns 0 on success, -1 on error.
  58. */
  59. static int disconnect_npipe (HPIPE hpipe)
  60. {
  61.   DosDisConnectNPipe (hpipe);
  62.   DosClose (hpipe);
  63.   return 0;
  64. }
  65.  
  66.  
  67. /*
  68. ** This is the thread for moving the data from one end to the other. When
  69. ** a client closes its connection to a named pipe, the named pipe will be
  70. ** closed and recreated.
  71. */
  72. void nmp_thread (void *ptr)
  73. {
  74.   APIRET apiret;
  75.   HPIPE  hpipe1, hpipe2;
  76.   ULONG  count1r = 0, count2w = 0, count2r = 0, count1w = 0, tmp;
  77.   AVAILDATA available1, available2;
  78.   ULONG  state1, state2;
  79.  
  80.   _named_pipe_ *nmp;
  81.   char data1[1024], data2[1024];
  82.   int rc, t = 10;
  83.  
  84.   nmp = (_named_pipe_ *) ptr;
  85.   nmp->result = 0;
  86.  
  87.   rc = create_npipe (nmp->name, &hpipe1);  if (rc)  goto end;
  88.   rc = create_npipe (nmp->name, &hpipe2);  if (rc)  goto end;
  89.  
  90.   DosPostEventSem (_hev_);
  91.   DosSetPriority (PRTYS_THREAD, PRTYC_IDLETIME, 0, nmp->tid);
  92.  
  93.   while (nmp->tid != -1)
  94.     {
  95.       apiret = DosPeekNPipe (hpipe1,&rc,sizeof(rc),&tmp,&available1,&state1);
  96.       if (apiret)  goto error;
  97.       apiret = DosPeekNPipe (hpipe2,&rc,sizeof(rc),&tmp,&available2,&state2);
  98.       if (apiret)  goto error;
  99.  
  100.       if (((available1.cbpipe <= 0) && (available2.cbpipe <= 0)) ||
  101.       ((state1 != NP_STATE_CONNECTED) && (state1 != NP_STATE_CLOSING)) ||
  102.       ((state2 != NP_STATE_CONNECTED) && (state1 != NP_STATE_CLOSING)))
  103.     {
  104.       DosSetPriority (PRTYS_THREAD, PRTYC_IDLETIME, 0, nmp->tid);
  105.  
  106.       if (t < 50) t++;
  107.       DosSleep (t);
  108.     }
  109.       else
  110.     {
  111.       DosSetPriority (PRTYS_THREAD, PRTYC_REGULAR, 0, nmp->tid);
  112.  
  113.       t = 0;
  114.     }
  115.  
  116.       if ((count1r > count2w) || (available1.cbpipe > 0))
  117.     {
  118.       if (count1r <= count2w)
  119.         {
  120.           apiret = DosRead (hpipe1, data1, sizeof(data1), &count1r);
  121.           if (apiret == 109)  goto restart1;
  122.           else if (apiret)    goto error;
  123.           count2w = 0;
  124.         }
  125.  
  126.       if (count1r > count2w)
  127.         {
  128.           apiret = DosWrite (hpipe2, data1+count2w, count1r-count2w, &tmp);
  129.           if (apiret == 109)  goto restart2;
  130.           else if (apiret)    goto error;
  131.           count2w += tmp;
  132.         }
  133.     }
  134.  
  135.       if (state1 == NP_STATE_CLOSING)  goto restart1;
  136.  
  137.       if ((count2r > count1w) || (available2.cbpipe > 0))
  138.     {
  139.       if (count2r <= count1w)
  140.         {
  141.           apiret = DosRead (hpipe2, data2, sizeof(data2), &count2r);
  142.           if (apiret == 109)  goto restart2;
  143.           else if (apiret)    goto error;
  144.           count1w = 0;
  145.         }
  146.  
  147.       if (count2r > count1w)
  148.         {
  149.           apiret = DosWrite (hpipe1, data2+count1w, count2r-count1w, &tmp);
  150.           if (apiret == 109)  goto restart1;
  151.           else if (apiret)    goto error;
  152.           count1w += tmp;
  153.         }
  154.     }
  155.  
  156.       if (state2 == NP_STATE_CLOSING)  goto restart2;
  157.  
  158.       continue;
  159.  
  160.     restart1:
  161.       disconnect_npipe (hpipe1);
  162.       rc = create_npipe (nmp->name, &hpipe1);
  163.       if (rc)  goto error;
  164.       continue;
  165.  
  166.     restart2:
  167.       disconnect_npipe (hpipe2);
  168.       rc = create_npipe (nmp->name, &hpipe2);
  169.       if (rc)  goto error;
  170.       continue;
  171.     }
  172.  
  173. end:
  174.   nmp->tid    = -1;
  175.   disconnect_npipe (hpipe1);
  176.   disconnect_npipe (hpipe2);
  177.  
  178.   _endthread ();
  179.   return;
  180.  
  181. error:
  182.   nmp->result = -1;
  183.   nmp->tid    = -1;
  184.  
  185.   disconnect_npipe (hpipe1);
  186.   disconnect_npipe (hpipe2);
  187.  
  188.   _endthread ();
  189.   return;
  190. }
  191.