"Fossies" - the Fresh Open Source Software Archive 
Member "postal-0.76/thread.cpp" (10 Apr 2008, 3662 Bytes) of package /linux/privat/postal-0.76.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 "thread.cpp" see the
Fossies "Dox" file reference documentation.
1 #include <stdlib.h>
2 #include "thread.h"
3 #include <stdio.h>
4 #include <errno.h>
5
6 #include <unistd.h>
7 #include <time.h>
8 #include <sys/types.h>
9 #include <sys/wait.h>
10 #include <pthread.h>
11
12 Thread::Thread()
13 : m_read(-1)
14 , m_write(-1)
15 , m_threadNum(-1)
16
17 , m_parentRead(-1)
18 , m_parentWrite(-1)
19 , m_childRead(-1)
20 , m_childWrite(-1)
21 , m_numThreads(0)
22 , m_retVal(NULL)
23 , m_thread_info(NULL)
24 {
25 }
26
27 Thread::Thread(int threadNum, const Thread *parent)
28 : m_read(parent->m_childRead)
29 , m_write(parent->m_childWrite)
30 , m_threadNum(threadNum)
31
32 , m_parentRead(-1)
33 , m_parentWrite(-1)
34 , m_childRead(-1)
35 , m_childWrite(-1)
36 , m_numThreads(parent->m_numThreads)
37 , m_retVal(&parent->m_retVal[threadNum])
38 , m_thread_info(NULL)
39 {
40 }
41
42 Thread::~Thread()
43 {
44 if(m_threadNum == -1)
45 {
46 for(int i = 0; i < m_numThreads; i++)
47 {
48 pthread_join(m_thread_info[i], NULL);
49 }
50 close(m_parentRead);
51 close(m_parentWrite);
52 close(m_childRead);
53 close(m_childWrite);
54 delete m_thread_info;
55 delete m_retVal;
56 }
57 }
58
59 // for the benefit of this function and the new Thread class it may create
60 // the Thread class must do nothing of note in it's constructor or it's
61 // go() member function.
62 PVOID thread_func(PVOID param)
63 {
64 THREAD_DATA *td = (THREAD_DATA *)param;
65 Thread *thread = td->f->newThread(td->threadNum);
66 thread->setRetVal(thread->action(td->param));
67 delete thread;
68 delete td;
69 return NULL;
70 }
71
72 void Thread::go(PVOID param, int num)
73 {
74 m_numThreads += num;
75 int control[2];
76 int feedback[2];
77 if (pipe(feedback) || pipe(control))
78 {
79 fprintf(stderr, "Can't open pipes.\n");
80 exit(1);
81 }
82 m_parentRead = feedback[0];
83 m_parentWrite = control[1];
84 m_childRead = control[0];
85 m_childWrite = feedback[1];
86 m_read = m_parentRead;
87 m_write = m_parentWrite;
88 m_readPoll.events = POLLIN | POLLERR | POLLHUP | POLLNVAL;
89 m_writePoll.events = POLLOUT | POLLERR | POLLHUP | POLLNVAL;
90 m_readPoll.fd = m_parentRead;
91 m_writePoll.fd = m_parentWrite;
92 pthread_attr_t attr;
93 if(pthread_attr_init(&attr)
94 || pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE)
95 || pthread_attr_setstacksize(&attr, 32*1024))
96 fprintf(stderr, "Can't set thread attributes.\n");
97
98 m_retVal = new int[num + 1];
99 m_thread_info = new pthread_t[num];
100 for(int i = 1; i <= num; i++)
101 {
102 m_retVal[i] = -1;
103 THREAD_DATA *td = new THREAD_DATA;
104 td->f = this;
105 td->param = param;
106 td->threadNum = i;
107 int p = pthread_create(&m_thread_info[i - 1], &attr, thread_func, PVOID(td));
108 if(p)
109 {
110 fprintf(stderr, "Can't create a thread.\n");
111 exit(1);
112 }
113 }
114 if(pthread_attr_destroy(&attr))
115 fprintf(stderr, "Can't destroy thread attributes.\n");
116 m_readPoll.fd = m_read;
117 m_writePoll.fd = m_write;
118 }
119
120 void Thread::setRetVal(int rc)
121 {
122 *m_retVal = rc;
123 }
124
125 int Thread::Read(PVOID buf, int size, int timeout)
126 {
127 if(timeout)
128 {
129 int rc = poll(&m_readPoll, 1, timeout * 1000);
130 if(rc < 0)
131 {
132 fprintf(stderr, "Can't poll read ITC.\n");
133 return -1;
134 }
135 if(!rc)
136 return 0;
137 }
138 if(size != read(m_read, buf, size) )
139 {
140 fprintf(stderr, "Can't read data from ITC pipe.\n");
141 return -1;
142 }
143 return size;
144 }
145
146 int Thread::Write(PVOID buf, int size, int timeout)
147 {
148 if(timeout)
149 {
150 int rc;
151 do
152 {
153 rc = poll(&m_writePoll, 1, timeout * 1000);
154 if(rc < 0 && errno != EINTR)
155 {
156 fprintf(stderr, "Can't poll write ITC.\n");
157 return -1;
158 }
159 } while(rc == -1);
160 if(!rc)
161 return 0;
162 }
163 if(size != write(m_write, buf, size))
164 {
165 fprintf(stderr, "Can't write data to ITC pipe.\n");
166 return -1;
167 }
168 return size;
169 }
170