"Fossies" - the Fresh Open Source Software Archive

Member "bonnie++-1.04/forkit.cpp" (3 Jul 2009, 3657 Bytes) of package /linux/privat/bonnie++_1.04.tgz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "forkit.cpp" see the Fossies "Dox" file reference documentation.

    1 
    2 #ifdef OS2
    3 #define INCL_DOSPROCESS
    4 #else
    5 #include <unistd.h>
    6 #include <time.h>
    7 #include <stdlib.h>
    8 #include <sys/wait.h>
    9 #endif
   10 
   11 #include "forkit.h"
   12 
   13 
   14 Fork::Fork()
   15  : m_read(-1)
   16  , m_write(-1)
   17  , m_numThreads(0)
   18 {
   19 }
   20 
   21 #ifdef OS2
   22 // for the benefit of this function and the new Fork class it may create
   23 // the Fork class must do nothing of note in it's constructor or it's
   24 // go() member function.
   25 VOID APIENTRY thread_func(ULONG param)
   26 {
   27   THREAD_DATA *td = (THREAD_DATA *)param;
   28   td->f = new Fork;
   29   td->f->startit(td);
   30 }
   31 #endif
   32 
   33 void Fork::startit(THREAD_DATA *td)
   34 {
   35   m_read = td->child_read;
   36   m_write = td->child_write;
   37   td->func(this, td->param, td->threadNum);
   38   delete td->f; // delete ourself if td->f is not NULL
   39   delete td;
   40   exit(0);
   41 }
   42 
   43 void Fork::go(FUNCTION func, PVOID param, int num)
   44 {
   45   m_numThreads = num;
   46   FILE_TYPE control[2];
   47   FILE_TYPE feedback[2];
   48   if (pipe(feedback) || pipe(control))
   49   {
   50     fprintf(stderr, "Can't open pipes.\n");
   51     exit(1);
   52   }
   53 #ifndef OS2
   54   m_readPoll.events = POLLIN | POLLERR | POLLHUP | POLLNVAL;
   55   m_writePoll.events = POLLOUT | POLLERR | POLLHUP | POLLNVAL;
   56 #endif
   57 
   58   THREAD_DATA *td = new THREAD_DATA;
   59   td->child_read = control[0];
   60   td->child_write = feedback[1];
   61   td->f = NULL;
   62   td->param = param;
   63   td->func = func;
   64   for(int i = 0; i < num; i++)
   65   {
   66 #ifdef OS2
   67     THREAD_DATA *tmp = new THREAD_DATA;
   68     memcpy(tmp, td, sizeof(THREAD_DATA));
   69 #endif
   70     td->threadNum = i;
   71 #ifdef OS2
   72     // yes I know I am casting a pointer to an unsigned long
   73     // it's the way you're supposed to do things in OS/2
   74     TID id = 0;
   75     if(DosCreateThread(&id, thread_func, ULONG(td), CREATE_READY, 32*1024))
   76     {
   77       fprintf(stderr, "Can't create a thread.\n");
   78       exit(1);
   79     }
   80 #else
   81     int p = fork();
   82     if(p == -1)
   83     {
   84       fprintf(stderr, "Can't fork.\n");
   85       exit(1);
   86     }
   87     if(p == 0) // child
   88     {
   89       m_readPoll.fd = td->child_read;
   90       m_writePoll.fd = td->child_write;
   91       file_close(control[1]);
   92       file_close(feedback[0]);
   93       srand(getpid() ^ time(NULL));
   94       startit(td);
   95     }
   96 #endif
   97   }
   98   // now we're in the parent thread/process
   99   m_write = control[1];
  100   m_read = feedback[0];
  101 #ifndef OS2
  102   m_readPoll.fd = m_read;
  103   m_writePoll.fd = m_write;
  104   file_close(control[0]);
  105   file_close(feedback[1]);
  106 #endif
  107 }
  108 
  109 int Fork::wait()
  110 {
  111 #ifdef OS2
  112   TID status = 0;
  113   if(DosWaitThread(&status, DCWW_WAIT))
  114   {
  115     fprintf(stderr, "Can't wait for thread.\n");
  116     return 1;
  117   }
  118 #else
  119   int status = 0;
  120   if(::wait(&status) == -1)
  121   {
  122     fprintf(stderr, "Can't wait for thread.\n");
  123     return 1;
  124   }
  125 #endif
  126   return 0;
  127 }
  128 
  129 int Fork::Read(PVOID buf, int size, int timeout)
  130 {
  131 #ifndef OS2
  132   if(timeout)
  133   {
  134     int rc = poll(&m_readPoll, 1, timeout * 1000);
  135     if(rc < 0)
  136     {
  137       fprintf(stderr, "Can't poll.\n");
  138       return -1;
  139     }
  140     if(!rc)
  141       return 0;
  142   }
  143 #endif
  144 #ifdef OS2
  145   unsigned long actual;
  146   int rc = DosRead(m_read, buf, size, &actual);
  147   if(rc || actual != size)
  148 #else
  149   if(size != read(m_read, buf, size) )
  150 #endif
  151   {
  152     fprintf(stderr, "Can't read data from IPC pipe.\n");
  153     return -1;
  154   }
  155   return size;
  156 }
  157 
  158 int Fork::Write(PVOID buf, int size, int timeout)
  159 {
  160 #ifndef OS2
  161   if(timeout)
  162   {
  163     int rc = poll(&m_writePoll, 1, timeout * 1000);
  164     if(rc < 0)
  165     {
  166       fprintf(stderr, "Can't poll for write.\n");
  167       return -1;
  168     }
  169     if(!rc)
  170       return 0;
  171   }
  172 #endif
  173 #ifdef OS2
  174   unsigned long actual;
  175   int rc = DosWrite(m_write, buf, size, &actual);
  176   if(rc || actual != size)
  177 #else
  178   if(size != write(m_write, buf, size))
  179 #endif
  180   {
  181     fprintf(stderr, "Can't write data to IPC pipe.\n");
  182     return -1;
  183   }
  184   return size;
  185 }
  186