43#include "InternalErr.h"
44#include "MarshallerThread.h"
51bool MarshallerThread::print_time =
false;
58static double time_diff_to_hundredths(
struct timeval *stop,
struct timeval *start)
61 if (stop->tv_usec < start->tv_usec) {
62 int nsec = (start->tv_usec - stop->tv_usec) / 1000000 + 1;
63 start->tv_usec -= 1000000 * nsec;
64 start->tv_sec += nsec;
66 if (stop->tv_usec - start->tv_usec > 1000000) {
67 int nsec = (start->tv_usec - stop->tv_usec) / 1000000;
68 start->tv_usec += 1000000 * nsec;
69 start->tv_sec -= nsec;
72 double result = stop->tv_sec - start->tv_sec;
73 result += double(stop->tv_usec - start->tv_usec) / 1000000;
87Locker::Locker(pthread_mutex_t &lock, pthread_cond_t &cond,
int &count) : m_mutex(lock) {
88 int status = pthread_mutex_lock(&m_mutex);
90 DBG(cerr <<
"Locking the mutex! (waiting; " << pthread_self() <<
")" << endl);
93 throw InternalErr(__FILE__, __LINE__,
"Could not lock m_mutex");
95 status = pthread_cond_wait(&cond, &m_mutex);
97 throw InternalErr(__FILE__, __LINE__,
"Could not wait on m_cond");
100 throw InternalErr(__FILE__, __LINE__,
"FAIL: left m_cond wait with non-zero child thread count");
102 DBG(cerr <<
"Locked! (" << pthread_self() <<
")" << endl);
109 DBG(cerr <<
"Unlocking the mutex! (" << pthread_self() <<
")" << endl);
111 (void)pthread_mutex_unlock(&m_mutex);
113 int status = pthread_mutex_unlock(&m_mutex);
114 if (status != 0)
throw InternalErr(__FILE__, __LINE__,
"Could not unlock m_mutex");
132 : m_mutex(lock), m_cond(cond), m_count(count) {
133 int status = pthread_mutex_lock(&m_mutex);
135 DBG(cerr <<
"Locking the mutex! (simple; " << pthread_self() <<
")" << endl);
138 throw InternalErr(__FILE__, __LINE__,
"Could not lock m_mutex");
140 DBG(cerr <<
"Locked! (" << pthread_self() <<
")" << endl);
143ChildLocker::~ChildLocker() {
144 DBG(cerr <<
"Unlocking the mutex! (" << pthread_self() <<
")" << endl);
148 (void)pthread_cond_signal(&m_cond);
149 (void)pthread_mutex_unlock(&m_mutex);
152 int status = pthread_cond_signal(&m_cond);
154 throw InternalErr(__FILE__, __LINE__,
"Could not signal main thread from ChildLocker!");
156 status = pthread_mutex_unlock(&m_mutex);
157 if (status != 0)
throw InternalErr(__FILE__, __LINE__,
"Could not unlock m_mutex");
161MarshallerThread::MarshallerThread() : d_thread(0), d_child_thread_count(0) {
162 if (pthread_attr_init(&d_thread_attr) != 0)
163 throw Error(internal_error,
"Failed to initialize pthread attributes.");
164 if (pthread_attr_setdetachstate(&d_thread_attr, PTHREAD_CREATE_DETACHED ) != 0)
165 throw Error(internal_error,
"Failed to complete pthread attribute initialization.");
167 if (pthread_mutex_init(&d_out_mutex, 0) != 0)
168 throw Error(internal_error,
"Failed to initialize mutex.");
169 if (pthread_cond_init(&d_out_cond, 0) != 0)
170 throw Error(internal_error,
"Failed to initialize cond.");
173MarshallerThread::~MarshallerThread() {
174 (void)pthread_mutex_lock(&d_out_mutex);
176 int status = pthread_mutex_lock(&d_out_mutex);
177 if (status != 0)
throw InternalErr(__FILE__, __LINE__,
"Could not lock m_mutex");
181 if (d_child_thread_count != 0) {
182 (void)pthread_cond_wait(&d_out_cond, &d_out_mutex);
183 d_child_thread_count = 0;
185 status = pthread_cond_wait(&d_out_cond, &d_out_mutex);
186 if (status != 0)
throw InternalErr(__FILE__, __LINE__,
"Could not wait on m_cond");
190 (void)pthread_mutex_unlock(&d_out_mutex);
193 if (d_child_thread_count != 0)
194 throw InternalErr(__FILE__, __LINE__,
"FAIL: left m_cond wait with non-zero child thread count");
196 status = pthread_mutex_unlock(&d_out_mutex);
197 if (status != 0)
throw InternalErr(__FILE__, __LINE__,
"Could not unlock m_mutex");
200 pthread_mutex_destroy(&d_out_mutex);
201 pthread_cond_destroy(&d_out_cond);
203 pthread_attr_destroy(&d_thread_attr);
214 new write_args(d_out_mutex, d_out_cond, d_child_thread_count, d_thread_error, out, byte_buf, bytes);
215 int status = pthread_create(&d_thread, &d_thread_attr, thread, args);
217 throw InternalErr(__FILE__, __LINE__,
"Could not start child thread");
225 new write_args(d_out_mutex, d_out_cond, d_child_thread_count, d_thread_error, fd, byte_buf, bytes);
226 int status = pthread_create(&d_thread, &d_thread_attr, thread, args);
228 throw InternalErr(__FILE__, __LINE__,
"Could not start child thread");
241 write_args *args =
reinterpret_cast<write_args *
>(arg);
243 ChildLocker lock(args->d_mutex, args->d_cond, args->d_count);
247 if (print_time && gettimeofday(&tp_s, 0) != 0) cerr <<
"could not read time" << endl;
253 if (args->d_out_file != -1) {
254 int bytes_written = write(args->d_out_file, args->d_buf, args->d_num);
255 if (bytes_written != args->d_num)
258 args->d_out.write(args->d_buf, args->d_num);
259 if (args->d_out.fail()) {
261 oss <<
"Could not write data: " << __FILE__ <<
":" << __LINE__;
262 args->d_error = oss.str();
267 delete[] args->d_buf;
273 if (gettimeofday(&tp_e, 0) != 0) cerr <<
"could not read time" << endl;
275 cerr <<
"time for child thread write: " << time_diff_to_hundredths(&tp_e, &tp_s) << endl;
295 write_args *args =
reinterpret_cast<write_args *
>(arg);
297 ChildLocker lock(args->d_mutex, args->d_cond, args->d_count);
299 if (args->d_out_file != -1) {
300 int bytes_written = write(args->d_out_file, args->d_buf, args->d_num);
301 if (bytes_written != args->d_num)
304 args->d_out.write(args->d_buf + 4, args->d_num);
305 if (args->d_out.fail()) {
307 oss <<
"Could not write data: " << __FILE__ <<
":" << __LINE__;
308 args->d_error = oss.str();
313 delete[] args->d_buf;
ChildLocker(pthread_mutex_t &lock, pthread_cond_t &cond, int &count)
A class for error processing.
A class for software fault reporting.
Locker(pthread_mutex_t &lock, pthread_cond_t &cond, int &count)
static void * write_thread(void *arg)
static void * write_thread_part(void *arg)
void start_thread(void *(*thread)(void *arg), std::ostream &out, char *byte_buf, unsigned int bytes_written)
top level DAP object to house generic methods