lugre_thread.cpp

Go to the documentation of this file.
00001 #include "lugre_prefix.h"
00002 #include "lugre_thread.h"
00003 #include "lugre_net.h"
00004 #include "lugre_fifo.h"
00005 #include "lugre_net.h"
00006 
00007 #include <iostream>
00008 #include <fstream>
00009 
00010 #ifdef ENABLE_THREADS
00011 #include <boost/thread/thread.hpp>
00012 #endif
00013 
00014 #define kThreadNetMinRecvSpace (1024*32)
00015 #define kThreadNetStartSpace (1024*32*2)
00016 
00017 // warning ! starting a thread makes a COPY of the passed in functor-object, so you cannot access the original
00018 // see http://boost.org/doc/html/boost/thread.html#id1291385-bb for details
00019 // http://www.boost.org/doc/libs/1_39_0/doc/html/thread.html
00020 
00021 // see also http://engineering.meta-comm.com/resources/cs-win32_1_30_2_metacomm/libs/thread/doc/thread.html
00022 // see also http://www-eleves-isia.cma.fr/documentation/BoostDoc/boost_1_29_0/libs/thread/example/thread_group.cpp
00023 // see also http://www-eleves-isia.cma.fr/documentation/BoostDoc/boost_1_29_0/libs/thread/example/thread.cpp
00024 
00025 /*
00026 int count = 0;
00027 boost::mutex mutex;
00028 
00029 void increment_count() {
00030     boost::mutex::scoped_lock lock(mutex);
00031     std::cout << "count = " << ++count << std::endl;
00032 }
00033 
00034 int main(int argc, char* argv[]) {
00035     boost::thread_group threads;
00036     for (int i = 0; i < 10; ++i)
00037         threads.create_thread(&increment_count);
00038     // thread* boost::thread_group::create_thread(const boost::function0<void>& threadfunc);
00039     threads.join_all();
00040 }
00041 
00042 #include <boost/thread/xtime.hpp>
00043 void something::operator()() {
00044     boost::xtime xt;
00045     boost::xtime_get(&xt, boost::TIME_UTC);
00046     xt.sec += m_secs;
00047 
00048     boost::thread::sleep(xt);
00049 
00050     std::cout << "alarm sounded..." << std::endl;
00051 }
00052 
00053 */
00054     
00055     
00056 namespace Lugre {
00057 
00058     
00059     
00060 // ##### ##### ##### ##### ##### cThread_NetRequest
00061     
00062 class cThread_NetRequestImpl { public:
00063     std::string     msHost;
00064     int             miPort;
00065     cFIFO*          mpSendData;
00066     cFIFO*          mpAnswerBuffer;
00067     int*            mpResultCode;
00068     
00069     cThread_NetRequestImpl  (int* pResultCode,const std::string& sHost,const int iPort,cFIFO* pSendData,cFIFO* pAnswerBuffer) :
00070         mpResultCode(pResultCode), msHost(sHost), miPort(iPort), mpSendData(pSendData), mpAnswerBuffer(pAnswerBuffer) {}
00071         
00072     void operator()() {
00073         do {
00074             // open connection
00075             uint32  iIP = cNet::GetHostByName(msHost.c_str());
00076             int     iSocket = cNet::ConnectSocket(iIP,miPort);
00077             if (cNet::IsInvalidSocket(iSocket)) {
00078                 printf("cThread_NetRequest : ConnectSocket failed (%s:%d)\n",msHost.c_str(),miPort);
00079                 break;
00080             }
00081             
00082             // send data
00083             if (mpSendData && mpSendData->size() > 0) {
00084                 int res = cNet::Send(iSocket,mpSendData->HackGetRawReader(),mpSendData->size(),0);
00085                 if (res != mpSendData->size()) { 
00086                     printf("cThread_NetRequest : sending failed (%s:%d) : %d\n",msHost.c_str(),miPort,res); 
00087                     break; 
00088                 }
00089             }
00090             
00091             // receive data
00092             if (mpAnswerBuffer) {
00093                 do {
00094                     char *rw = mpAnswerBuffer->HackGetRawWriter(kThreadNetMinRecvSpace);
00095                     int fs = mpAnswerBuffer->HackGetFreeSpace();
00096                     int res = cNet::Recv(iSocket,rw,fs,0);
00097                     if (res <= 0) break; // TODO : detect errors here ?
00098                     mpAnswerBuffer->HackAddLength(res);
00099                 } while (1);
00100             }
00101             
00102             // close connection
00103             cNet::CloseSocket(iSocket);
00104             
00105             // finish thread
00106             *mpResultCode = 0;
00107             return;
00108             // success
00109         } while (0) ;
00110         
00111         // if we come here some error occurred
00112         *mpResultCode = -1;
00113         // failed
00114     }
00115 };
00116     
00117 
00118 cThread_NetRequest::cThread_NetRequest      (const std::string& sHost,const int iPort,cFIFO* pSendData,cFIFO* pAnswerBuffer) {
00119     miResultCode = 1;
00120     cThread_NetRequestImpl myImpl(&miResultCode,sHost,iPort,pSendData,pAnswerBuffer);
00121 #ifdef ENABLE_THREADS
00122     // start thread, thread continues to exist even if this boost thread handle is destroyed, unless join is called
00123     boost::thread myboostthread(myImpl); // warning ! this COPIES the impl object
00124 #else
00125     // execute blocking
00126     myImpl();
00127 #endif
00128 }
00129 cThread_NetRequest::~cThread_NetRequest () {}
00130 
00131 
00132 
00133 // ##### ##### ##### ##### ##### cThread_LoadFile
00134 
00135 
00136 
00137 class cThread_LoadFileImpl { public:
00138     std::string     msFilePath;
00139     cFIFO*          mpAnswerBuffer;
00140     int             miStart;
00141     int             miLength;
00142     int*            mpResultCode;
00143     
00144     cThread_LoadFileImpl    (int* pResultCode,const std::string& sFilePath,cFIFO* pAnswerBuffer,const int iStart,const int iLength) :
00145         mpResultCode(pResultCode), msFilePath(sFilePath), mpAnswerBuffer(pAnswerBuffer), miStart(iStart), miLength(iLength) {}
00146         
00147     void operator()() {
00148         do {
00149             if (!mpAnswerBuffer) break;
00150             std::ifstream myFileStream(msFilePath.c_str(),std::ios_base::binary);
00151             if (!myFileStream) { printf("cThread_LoadFile : failed to open file %s (start=%d,len=%d)\n",msFilePath.c_str(),miStart,miLength); break; }
00152             myFileStream.seekg(0, std::ios::end);
00153             int iFullFileSize = myFileStream.tellg();
00154             int iReadStart = mymax(0,miStart);
00155             int iReadLen = (miLength < 0) ? iFullFileSize : mymin(iFullFileSize-iReadStart,miLength);
00156             
00157             myFileStream.seekg(iReadStart, std::ios::beg);
00158             
00159             char *pWriter = mpAnswerBuffer->HackGetRawWriter(iReadLen);
00160             myFileStream.read(pWriter,iReadLen); 
00161             mpAnswerBuffer->HackAddLength(iReadLen);
00162             myFileStream.close();
00163             
00164             // finish thread
00165             *mpResultCode = 0;
00166             return;
00167             // success
00168         } while (0) ;
00169         
00170         // if we come here some error occurred
00171         *mpResultCode = -1;
00172         // failed
00173     }
00174 };
00175 
00176 
00177 cThread_LoadFile::cThread_LoadFile      (const std::string& sFilePath,cFIFO* pAnswerBuffer,const int iStart,const int iLength) {
00178     miResultCode = 1;
00179     cThread_LoadFileImpl myImpl(&miResultCode,sFilePath,pAnswerBuffer,iStart,iLength);
00180 #ifdef ENABLE_THREADS
00181     // start thread, thread continues to exist even if this boost thread handle is destroyed, unless join is called
00182     boost::thread myboostthread(myImpl); // warning ! this COPIES the impl object
00183 #else
00184     // execute blocking
00185     myImpl();
00186 #endif
00187 }
00188 cThread_LoadFile::~cThread_LoadFile     () {}
00189 
00190 
00191 
00192 };

Generated on Wed May 23 06:00:15 2012 for cpp by  doxygen 1.5.6