/* * This file is a part of Winix * and is distributed under the 2-Clause BSD licence. * Author: Tomasz Sowa */ /* * Copyright (c) 2010-2019, Tomasz Sowa * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * */ #ifndef headerfile_winix_core_basethread #define headerfile_winix_core_basethread #include #include "synchro.h" #include "winixmodel.h" namespace Winix { class BaseThread : public WinixModel { public: BaseThread(); virtual ~BaseThread(); void set_main_log_buffer(pt::WTextStream * log_buffer); void set_main_file_log(pt::FileLog * file_log); // work mode // we have two modes: // 0 - there is a loop with SignalReceived() and Do() // if SignalReceived() returns true then Do() is called // 1 - only Work() method is called // the thread exits after Work() has finished // default: 0 void Mode(int mode); // starting the second thread bool StartThread(); // virtual methods which should/can be inherited by your class // the methods will be called from the other thread // wake up the second thread // (if it waits for the signal) // you should use it with: synchro->Lock() and Unlock() // if the thread doesn't wait on a signal then nothing is done virtual void WakeUpThread(); // waiting until the thread exits // you should call WakeUpThread() before virtual void WaitForThread(); // initialize the thread // (global objects are locked) // if it returns false then the thread immediately exits // default: true virtual bool Init() { return true; } // uninitialize the thread // this is called before the thread is prepare to detach // (global objects are locked) // it's called only if Init() returned true virtual void Uninit() {} // returns the thread id // this identifier is set by StartThread() metdhod pthread_t ThreadId(); protected: // logger for the main thread Log main_log; // log from WinixBase is meant to be used by the other thread protected: // signal came (work mode = 0 - default) // signal comes when an other thread calls WakeUpThread() method // check specific job and return true to call Do() next // (global objects are locked -- copy some global objects to local variables) virtual bool SignalReceived() { return false; }; // if SignalReceived() returned true then this method is called // global objects are *not* locked -- use only your local variables // if you have to do something on global objects use synchro->Lock() and synchro->Unlock() virtual void Do() {} // this method is called after Init() when Mode(1) is used // this is for long-time job // this method is called only once // global objects are *not* locked virtual void Work() {} protected: pthread_t thread_id; // thread id - set by StartThread() pthread_cond_t thread_signal; int work_mode; bool wake_up_was_called; void SignalLoop(); static void * StartRoutine(void *); bool BaseInit(); void BaseUninit(); bool BaseSignalReceived(); void BaseDo(); bool WaitForSignal(); bool WaitForSignalSleep(time_t second); bool Lock(); void Unlock(); // if the work done by Do() is long time consuming you should periodically check // wheter there was a signal for exiting, and if it was just simply return from Do() // (it's checking with locking and unlocking) bool IsExitSignal(); }; } // namespace Winix #endif