home *** CD-ROM | disk | FTP | other *** search
/ Frostbyte's 1980s DOS Shareware Collection / floppyshareware.zip / floppyshareware / DOOG / CTASK.ZIP / TSKPIP.C < prev    next >
C/C++ Source or Header  |  1989-12-20  |  6KB  |  295 lines

  1. /*
  2.     --- Version 2.0 89-12-14 13:33 ---
  3.  
  4.    TSKPIP.C - CTask - Pipe handling routines.
  5.  
  6.    Public Domain Software written by
  7.       Thomas Wagner
  8.       Patschkauer Weg 31
  9.       D-1000 Berlin 33
  10.       West Germany
  11. */
  12.  
  13. #include <stdio.h>
  14.  
  15. #include "tsk.h"
  16. #include "tsklocal.h"
  17.  
  18. /*
  19.    tsk_getcpipe - get a byte from a pipe. For internal use only.
  20.                   Critical section assumed entered.
  21. */
  22.  
  23. local byte near tsk_getcpipe (pipeptr pip)
  24. {
  25.    byte c;
  26.  
  27.    c = pip->contents [pip->outptr++];
  28.    if (pip->outptr >= pip->bufsize)
  29.       pip->outptr = 0;
  30.    pip->filled--;
  31.    return c;
  32. }
  33.  
  34.  
  35. /*
  36.    tsk_putcpipe - put a byte to a pipe. For internal use only.
  37.                   Critical section assumed entered.
  38. */
  39.  
  40. local void near tsk_putcpipe (pipeptr pip, byte c)
  41. {
  42.    pip->contents [pip->inptr++] = c;
  43.    if (pip->inptr >= pip->bufsize)
  44.       pip->inptr = 0;
  45.    pip->filled++;
  46. }
  47.  
  48.  
  49. /* -------------------------------------------------------------------- */
  50.  
  51.  
  52. /*
  53.    create_pipe - initialises pipe.
  54. */
  55.  
  56. pipeptr far create_pipe (pipeptr pip, farptr buf, word bufsize
  57. #if (TSK_NAMEPAR)
  58.                         ,byteptr name
  59. #endif
  60.                         )
  61. {
  62. #if (TSK_DYNAMIC)
  63.    if (pip == NULL)
  64.       {
  65.       if ((pip = tsk_alloc (sizeof (pipe))) == NULL)
  66.          return NULL;
  67.       pip->flags = F_TEMP;
  68.       }
  69.    else
  70.       pip->flags = 0;
  71.    if (buf == NULL)
  72.       {
  73.       if ((buf = tsk_alloc (bufsize)) == NULL)
  74.          {
  75.          if (pip->flags & F_TEMP)
  76.             tsk_free (pip);
  77.          return NULL;
  78.          }
  79.       pip->flags |= F_STTEMP;
  80.       }
  81. #endif
  82.  
  83.    tsk_init_qhead (&pip->wait_read);
  84.    tsk_init_qhead (&pip->wait_write);
  85.    tsk_init_qhead (&pip->wait_clear);
  86.    pip->outptr = pip->inptr = pip->filled = 0;
  87.    pip->bufsize = bufsize;
  88.    pip->contents = (byteptr)buf;
  89.  
  90. #if (TSK_NAMED)
  91.    tsk_add_name (&pip->name, name, TYP_PIPE, pip);
  92. #endif
  93.  
  94.    return pip;
  95. }
  96.  
  97.  
  98. /*
  99.    delete_pipe - kills all processes waiting for reading from or writing
  100.                  to the pipe.
  101. */
  102.  
  103. void far delete_pipe (pipeptr pip)
  104. {
  105.    CRITICAL;
  106.  
  107.    C_ENTER;
  108.    tsk_kill_queue (&(pip->wait_read));
  109.    tsk_kill_queue (&(pip->wait_write));
  110.    tsk_kill_queue (&(pip->wait_clear));
  111.    pip->outptr = pip->inptr = pip->filled = 0;
  112.    C_LEAVE;
  113.  
  114. #if (TSK_NAMED)
  115.    tsk_del_name (&pip->name);
  116. #endif
  117.  
  118. #if (TSK_DYNAMIC)
  119.    if (pip->flags & F_STTEMP)
  120.       tsk_free (pip->contents);
  121.    if (pip->flags & F_TEMP)
  122.       tsk_free (pip);
  123. #endif
  124. }
  125.  
  126.  
  127. /*
  128.    read_pipe - Wait until a character is written to the pipe. If there 
  129.                is a character in the pipe on entry, it is assigned to 
  130.                the caller, and the task continues to run. If there are
  131.                tasks waiting to write, the first task is made eligible,
  132.                and the character is inserted into the pipe.
  133. */
  134.  
  135. int far read_pipe (pipeptr pip, dword timeout)
  136. {
  137.    tcbptr curr;
  138.    int res;
  139.    CRITICAL;
  140.  
  141.    C_ENTER;
  142.  
  143.    if (pip->filled)
  144.       {
  145.       res = tsk_getcpipe (pip);
  146.  
  147.       if ((curr = (tcbptr)pip->wait_write.first)->cqueue.kind)
  148.          {
  149.          tsk_putcpipe (pip, (byte)curr->retsize);
  150.          tsk_runable (curr);
  151.          curr->retptr = NULL;
  152.          }
  153.       else if (!pip->filled)
  154.          tsk_runable_all (&pip->wait_clear);
  155.  
  156.       C_LEAVE;
  157.       return res;
  158.       }
  159.  
  160.    tsk_wait (&pip->wait_read, timeout);
  161.    return (int)GLOBDATA current_task->retptr;
  162. }
  163.  
  164.  
  165. /*
  166.    c_read_pipe - If there is a character in the pipe on entry,
  167.                  read_pipe is called, otherwise en error status is returned.
  168. */
  169.  
  170. int far c_read_pipe (pipeptr pip)
  171. {
  172.    CRITICAL, res;
  173.  
  174.    C_ENTER;
  175.    res = (pip->filled) ? read_pipe (pip, 0L) : -1;
  176.    C_LEAVE;
  177.    return res;
  178. }
  179.  
  180.  
  181.  
  182. /*
  183.    write_pipe - Wait until space for the character to be written to the 
  184.                 pipe is available. If there is enough space in the pipe 
  185.                 on entry, the character is inserted into the pipe, and
  186.                 the task continues to run. If there are tasks waiting 
  187.                 to read, the first task is made eligible, and the character
  188.                 is passed to the waiting task.
  189. */
  190.  
  191. int far write_pipe (pipeptr pip, byte ch, dword timeout)
  192. {
  193.    tcbptr curr;
  194.    CRITICAL;
  195.  
  196.    C_ENTER;
  197.  
  198.    if (pip->filled < pip->bufsize)
  199.       {
  200.       if ((curr = (tcbptr)pip->wait_read.first)->cqueue.kind)
  201.          {
  202.          tsk_runable (curr);
  203.          curr->retptr = (farptr)ch;
  204.          C_LEAVE;
  205.          return 0;
  206.          }
  207.  
  208.       tsk_putcpipe (pip, ch);
  209.       C_LEAVE;
  210.       return 0;
  211.       }
  212.  
  213.    GLOBDATA current_task->retsize = ch;
  214.    tsk_wait (&pip->wait_write, timeout);
  215.    return (int)GLOBDATA current_task->retptr;
  216. }
  217.  
  218.  
  219. /*
  220.    c_write_pipe - If there is space for the character in the pipe on entry,
  221.                   write_pipe is called, otherwise en error status is returned.
  222. */
  223.  
  224. int far c_write_pipe (pipeptr pip, byte ch)
  225. {
  226.    int res;
  227.    CRITICAL;
  228.  
  229.    C_ENTER;
  230.    res = (pip->filled < pip->bufsize) ? write_pipe (pip, ch, 0L) : -1;
  231.    C_LEAVE;
  232.    return res;
  233. }
  234.  
  235.  
  236. /*
  237.    wait_pipe_empty - Wait until the pipe is empty. If the pipe is
  238.                      empty on entry, the task continues to run.
  239. */
  240.  
  241. int far wait_pipe_empty (pipeptr pip, dword timeout)
  242. {
  243.    CRITICAL;
  244.  
  245.    C_ENTER;
  246.    if (!pip->filled)
  247.       {
  248.       C_LEAVE;
  249.       return 0;
  250.       }
  251.  
  252.    GLOBDATA current_task->retptr = NULL;
  253.    tsk_wait (&pip->wait_clear, timeout);
  254.    return (int)GLOBDATA current_task->retptr;
  255. }
  256.  
  257.  
  258. /*
  259.    check_pipe - returns -1 if there are no characters in the pipe, else
  260.                 the first available character.
  261. */
  262.  
  263. int far check_pipe (pipeptr pip)
  264. {
  265.    return (pip->filled) ? (int)pip->contents [pip->outptr] : -1;
  266. }
  267.  
  268.  
  269. /*
  270.    pipe_free - returns the number of free characters in the pipe.
  271. */
  272.  
  273. word far pipe_free (pipeptr pip)
  274. {
  275.    return pip->bufsize - pip->filled;
  276. }
  277.  
  278.  
  279. /*
  280.    flush_pipe - Empty the pipe buffer, activate tasks waiting for 
  281.                 pipe clear.
  282. */
  283.  
  284. void far flush_pipe (pipeptr pip)
  285. {
  286.    CRITICAL;
  287.  
  288.    C_ENTER;
  289.    pip->inptr = pip->outptr = pip->filled = 0;
  290.  
  291.    tsk_runable_all (&pip->wait_clear);
  292.    C_LEAVE;
  293. }
  294.  
  295.