"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