libdap  Updated for version 3.17.0
MarshallerThread.h
00001 
00002 // -*- mode: c++; c-basic-offset:4 -*-
00003 
00004 // This file is part of libdap, A C++ implementation of the OPeNDAP Data
00005 // Access Protocol.
00006 
00007 // Copyright (c) 2015 OPeNDAP, Inc.
00008 // Author: James Gallagher <jgallagher@opendap.org>
00009 //
00010 // This library is free software; you can redistribute it and/or
00011 // modify it under the terms of the GNU Lesser General Public
00012 // License as published by the Free Software Foundation; either
00013 // version 2.1 of the License, or (at your option) any later version.
00014 //
00015 // This library is distributed in the hope that it will be useful,
00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018 // Lesser General Public License for more details.
00019 //
00020 // You should have received a copy of the GNU Lesser General Public
00021 // License along with this library; if not, write to the Free Software
00022 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00023 //
00024 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
00025 
00026 /*
00027  * MarshallerThread.h
00028  *
00029  *  Created on: Aug 27, 2015
00030  *      Author: jimg
00031  */
00032 
00033 #ifndef MARSHALLERTHREAD_H_
00034 #define MARSHALLERTHREAD_H_
00035 
00036 #include <pthread.h>
00037 
00038 #include <iostream>
00039 #include <ostream>
00040 #include <string>
00041 
00042 namespace libdap {
00043 
00052 class Locker {
00053 public:
00054     Locker(pthread_mutex_t &lock, pthread_cond_t &cond, int &count);
00055     virtual ~Locker();
00056 
00057 private:
00058     pthread_mutex_t& m_mutex;
00059 
00060     Locker();
00061     Locker(const Locker &rhs);
00062 };
00063 
00069 class ChildLocker {
00070 public:
00071     ChildLocker(pthread_mutex_t &lock, pthread_cond_t &cond, int &count);
00072     virtual ~ChildLocker();
00073 
00074 private:
00075     pthread_mutex_t& m_mutex;
00076     pthread_cond_t& m_cond;
00077     int& m_count;
00078 
00079     ChildLocker();
00080     ChildLocker(const Locker &rhs);
00081 };
00082 
00083 class MarshallerThread {
00084 private:
00085     pthread_t d_thread;
00086     pthread_attr_t d_thread_attr;
00087 
00088     pthread_mutex_t d_out_mutex;
00089     pthread_cond_t d_out_cond;
00090 
00091     int d_child_thread_count;   // 0 or 1
00092     std::string d_thread_error; // non-null indicates an error
00093 
00094     static bool print_time; // false by default
00095 
00102     struct write_args {
00103         pthread_mutex_t &d_mutex;
00104         pthread_cond_t &d_cond;
00105         int &d_count;
00106         std::string &d_error;
00107         std::ostream &d_out;     // The output stream protected by the mutex, ...
00108         int d_out_file;       // file descriptor; if not -1, use this.
00109         char *d_buf;        // The data to write to the stream
00110         int d_num;          // The size of d_buf
00111 
00115         write_args(pthread_mutex_t &m, pthread_cond_t &c, int &count, std::string &e, std::ostream &s, char *vals, int num) :
00116             d_mutex(m), d_cond(c), d_count(count), d_error(e), d_out(s), d_out_file(-1), d_buf(vals), d_num(num)
00117         {
00118         }
00119 
00124         write_args(pthread_mutex_t &m, pthread_cond_t &c, int &count, std::string &e, int fd, char *vals, int num) :
00125             d_mutex(m), d_cond(c), d_count(count), d_error(e), d_out(std::cerr), d_out_file(fd), d_buf(vals), d_num(num)
00126         {
00127         }
00128    };
00129 
00130 public:
00131     MarshallerThread();
00132     virtual ~MarshallerThread();
00133 
00134     pthread_mutex_t &get_mutex() { return d_out_mutex; }
00135     pthread_cond_t &get_cond() { return d_out_cond; }
00136 
00137     int &get_child_thread_count() { return d_child_thread_count; }
00138     void increment_child_thread_count() { ++d_child_thread_count; }
00139 
00140     void start_thread(void* (*thread)(void *arg), std::ostream &out, char *byte_buf, unsigned int bytes_written);
00141     void start_thread(void* (*thread)(void *arg), int fd, char *byte_buf, unsigned int bytes_written);
00142 
00143     // These are static so they will have c-linkage - required because they
00144     // are passed to pthread_create()
00145     static void *write_thread(void *arg);
00146     static void *write_thread_part(void *arg);
00147 
00148     static void set_print_time(bool state) { print_time = state; }
00149     static bool get_print_time() { return print_time; }
00150 };
00151 
00152 }
00153 
00154 #endif /* MARSHALLERTHREAD_H_ */