MASA-Core
AbstractAlignerSafe.hpp
Go to the documentation of this file.
00001 /*******************************************************************************
00002  *
00003  * Copyright (c) 2010-2015   Edans Sandes
00004  *
00005  * This file is part of MASA-Core.
00006  * 
00007  * MASA-Core is free software: you can redistribute it and/or modify
00008  * it under the terms of the GNU General Public License as published by
00009  * the Free Software Foundation, either version 3 of the License, or
00010  * (at your option) any later version.
00011  * 
00012  * MASA-Core is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  * 
00017  * You should have received a copy of the GNU General Public License
00018  * along with MASA-Core.  If not, see <http://www.gnu.org/licenses/>.
00019  *
00020  ******************************************************************************/
00021 
00022 #ifndef ABSTRACTALIGNERSAFE_HPP_
00023 #define ABSTRACTALIGNERSAFE_HPP_
00024 
00025 #include "AbstractAligner.hpp"
00026 #include <pthread.h>
00027 #include <queue>
00028 using namespace std;
00029 
00030 
00031 struct dispatch_job_t {
00032         enum dispatch_type_e {JOB_SCORE} type;
00033         union dispatch_params_t {
00034                 struct params_score_t {
00035                         score_t score;
00036                         int bx;
00037                         int by;
00038                 } params_score;
00039         } dispatch_params;
00040 };
00041 
00042 /** @brief A thread-safe AbstractAligner extension.
00043  *
00044  * The current MASA implementation is not thread-safe. So, if an Aligner
00045  * executes simultaneous threads, the dispatch methods may generate an
00046  * inconsistent state leading to segmentation faults. To avoid this behavior,
00047  * the Aligner must extend the AbstractAlignerSafe class in order to
00048  * serialize the dispatch calls.
00049  *
00050  * There are two serialization strategies.
00051  *
00052  * <ul>
00053  *  <li>Serialize by Mutex: the class uses mutex to lock simultaneous threads.
00054  *      The threads are locked until no other thread is dispatching.
00055  *  <li>Serialize by Queue: the class enqueue all dispatch executions and a
00056  *      consumer thread dispatches the requisitions to the MASA engine. The
00057  *      threads are only locked during the enqueue process. By now, only the
00058  *      dispatchScore function is queued. To enable this feature, use
00059  *      the createDispatcherQueue and destroyDispatcherQueue in the
00060  *      alignPartition method.
00061  * </ul>
00062  */
00063 class AbstractAlignerSafe : public AbstractAligner {
00064 public:
00065         AbstractAlignerSafe();
00066         virtual ~AbstractAlignerSafe();
00067 
00068         virtual void dispatchColumn(int j, const cell_t* buffer, int len);
00069         virtual void dispatchRow(int i, const cell_t* buffer, int len);
00070         virtual void dispatchScore(score_t score, int bx=-1, int by=-1);
00071 
00072 protected:
00073         void createDispatcherQueue();
00074         void destroyDispatcherQueue();
00075 
00076 private:
00077         pthread_t thread;
00078         pthread_mutex_t mutex;
00079         pthread_cond_t condition;
00080         bool dispatcherQueueActive;
00081         queue<dispatch_job_t> dispatcherQueue;
00082 
00083         static void *staticFunctionThread(void *arg);
00084         void executeLoop();
00085 };
00086 
00087 #endif /* ABSTRACTALIGNERSAFE_HPP_ */