Commit dc6e0aea authored by Pavel Vainerman's avatar Pavel Vainerman

Рефакториг работы с потоками (ThreadCreator), ушёл от использования самописного…

Рефакториг работы с потоками (ThreadCreator), ушёл от использования самописного PosixThread и перешёл на использование gnucc-шного.
parent 6dad1d83
......@@ -212,7 +212,6 @@ AC_CONFIG_FILES([Makefile
src/ObjectRepository/Makefile
src/Processes/Makefile
src/Services/Makefile
src/Threads/Makefile
src/Timers/Makefile
src/Various/Makefile
src/Makefile
......
......@@ -8,7 +8,7 @@ bin_PROGRAMS = @PACKAGE@-smemory-plus
$(top_builddir)/extensions/IOControl/libUniSetIOControl.la \
$(top_builddir)/extensions/SharedMemory/libUniSetSharedMemory.la \
$(top_builddir)/extensions/lib/libUniSetExtensions.la \
$(SIGC_LIBS)
$(SIGC_LIBS) $(COMCPP_LIBS)
@PACKAGE@_smemory_plus_CXXFLAGS = -I$(top_builddir)/extensions/CanNetwork \
-I$(top_builddir)/extensions/UNetUDP \
......@@ -17,6 +17,6 @@ bin_PROGRAMS = @PACKAGE@-smemory-plus
-I$(top_builddir)/extensions/IOControl \
-I$(top_builddir)/extensions/SharedMemory \
-I$(top_builddir)/extensions/include \
$(SIGC_CFLAGS)
$(SIGC_CFLAGS) $(COMCPP_CFLAGS)
@PACKAGE@_smemory_plus_SOURCES = smemory-plus.cc
......@@ -84,6 +84,7 @@ class PassiveTimer:
public:
PassiveTimer();
PassiveTimer( timeout_t timeMS ); /*!< установить таймер */
~PassiveTimer();
virtual bool checkTime(); /*!< проверка наступления заданного времени */
......
......@@ -37,7 +37,7 @@ public:
virtual ~PosixThread();
void start( void *args ); /*!< запуск */
void stop();
void stop();
void thrkill( int signo ); /*!< послать сигнал signo */
......@@ -51,8 +51,6 @@ public:
static void* funcp( void * test );
protected:
void reinit();
......@@ -77,5 +75,6 @@ private:
static int countThreads;
};
//----------------------------------------------------------------------------------------
#endif // PosixThread_h_
//----------------------------------------------------------------------------------------
......@@ -25,7 +25,7 @@
#ifndef ThreadCreator_h_
#define ThreadCreator_h_
//----------------------------------------------------------------------------------------
#include "PosixThread.h"
#include <cc++/thread.h>
//----------------------------------------------------------------------------------------
/*! \class ThreadCreator
* Шаблон для создания потоков с указанием функции вызова.
......@@ -83,36 +83,53 @@
//----------------------------------------------------------------------------------------
template<class ThreadMaster>
class ThreadCreator:
protected PosixThread
public ost::PosixThread
{
public:
/*! прототип функции вызова */
typedef void(ThreadMaster::* Action)(void);
typedef void(ThreadMaster::* Action)(void);
ThreadCreator( ThreadMaster* m, Action a );
~ThreadCreator();
pthread_t start();
pthread_t getTID(){ return PosixThread::getTID(); }
void stop();
inline void stop()
inline void setPriority( int ptior )
{
PosixThread::stop();
#warning ThreadCreator::setPriority NOT REALIZED YET
}
inline void kill( int signo ) /*!< послать сигнал signo */
inline void setCancel( ost::Thread::Cancel mode )
{
PosixThread::thrkill(signo);
ost::PosixThread::setCancel(mode);
}
inline void setPriority( int priority )
inline void setFinalAction( ThreadMaster* m, Action a )
{
PosixThread::setPriority(priority);
finm = m;
finact = a;
}
ThreadCreator( ThreadMaster* m, Action a );
~ThreadCreator();
inline void setInitialAction( ThreadMaster* m, Action a )
{
initm = m;
initact = a;
}
protected:
virtual void work(); /*!< Функция выполняемая в потоке */
virtual void run();
virtual void final()
{
if( finm )
(finm->*finact)();
}
virtual void initial()
{
if( initm )
(initm->*initact)();
}
private:
ThreadCreator();
......@@ -120,18 +137,27 @@ class ThreadCreator:
ThreadMaster* m;
Action act;
ThreadMaster* finm;
Action finact;
ThreadMaster* initm;
Action initact;
};
//----------------------------------------------------------------------------------------
template <class ThreadMaster>
ThreadCreator<ThreadMaster>::ThreadCreator( ThreadMaster* m, Action a ):
m(m),
act(a)
act(a),
finm(0),
finact(0),
initm(0),
initact(0)
{
}
//----------------------------------------------------------------------------------------
template <class ThreadMaster>
void ThreadCreator<ThreadMaster>::work()
void ThreadCreator<ThreadMaster>::run()
{
if(m)
(m->*act)();
......@@ -139,17 +165,19 @@ void ThreadCreator<ThreadMaster>::work()
}
//----------------------------------------------------------------------------------------
template <class ThreadMaster>
pthread_t ThreadCreator<ThreadMaster>::start()
void ThreadCreator<ThreadMaster>::stop()
{
PosixThread::start( static_cast<PosixThread*>(this) );
return getTID();
terminate();
}
//----------------------------------------------------------------------------------------
template <class ThreadMaster>
ThreadCreator<ThreadMaster>::ThreadCreator():
m(0),
act(0)
act(0),
finm(0),
finact(0),
initm(0),
initact(0)
{
}
//----------------------------------------------------------------------------------------
......
#ifndef _TCPCheck_H_
#define _TCPCheck_H_
// -----------------------------------------------------------------------------
#include <cc++/socket.h>
#include "Mutex.h"
#include "ThreadCreator.h"
// -----------------------------------------------------------------------------
/*! Вспомогательный класс для проверки связи, реализованный через создание потока,
чтобы при проверке не было "зависания" при недоступности адреса.
Смысл: создаётся поток, в нём происходит проверка, а в вызвавший поток приостанавливается
на время timeout, по истечении которого созданный поток "принудительно"(в любом случае)
уничтожается..
*/
class TCPCheck
{
public:
TCPCheck();
~TCPCheck();
bool check( const std::string& _ip, int _port, timeout_t tout, timeout_t sleep_msec );
/*! \param iaddr - 'ip:port' */
bool check( const std::string& iaddr, timeout_t tout, timeout_t sleep_msec );
protected:
void check_thread();
inline void setResult( bool res )
{
UniSetTypes::uniset_mutex_lock l(m,50);
result = res;
}
inline bool getResult()
{
bool res = false;
{
UniSetTypes::uniset_mutex_lock l(m,50);
res = result;
}
return res;
}
bool result;
std::string iaddr;
int tout_msec;
UniSetTypes::uniset_mutex m;
};
// -----------------------------------------------------------------------------
#endif // _TCPCheck_H_
// -----------------------------------------------------------------------------
......@@ -20,7 +20,6 @@ libUniSet_la_LIBADD = \
$(top_builddir)/src/ObjectRepository/libObjectsRepository.la \
$(top_builddir)/src/Processes/libProcesses.la \
$(top_builddir)/src/Services/libServices.la \
$(top_builddir)/src/Threads/libThreads.la \
$(top_builddir)/src/Timers/libTimers.la \
$(top_builddir)/src/Various/libVarious.la
......@@ -5,7 +5,7 @@ noinst_LTLIBRARIES = libModbus.la
libModbus_la_SOURCES = ModbusTypes.cc ModbusHelpers.cc \
ModbusClient.cc ModbusServer.cc ModbusServerSlot.cc \
ModbusRTUSlave.cc ModbusRTUSlaveSlot.cc ModbusRTUMaster.cc \
ModbusTCPCore.cc ModbusTCPServer.cc ModbusTCPServerSlot.cc ModbusTCPMaster.cc
ModbusTCPCore.cc ModbusTCPServer.cc ModbusTCPServerSlot.cc ModbusTCPMaster.cc TCPCheck.cc
libModbus_la_CXXFLAGS = -I$(top_builddir)/include/Communications/modbus $(SIGC_CFLAGS) $(COMCPP_CFLAGS)
libModbus_la_LIBADD = $(SIGC_LIBS) $(COMCPP_LIBS)
......
// -----------------------------------------------------------------------------
#include <sstream>
#include "UniSetTypes.h"
#include "PassiveTimer.h"
#include "modbus/TCPCheck.h"
// -----------------------------------------------------------------------------
using namespace std;
// -----------------------------------------------------------------------------
TCPCheck::TCPCheck():
iaddr(""),tout_msec(0)
{
}
// -----------------------------------------------------------------------------
TCPCheck::~TCPCheck()
{
}
// -----------------------------------------------------------------------------
bool TCPCheck::check( const std::string& ip, int port, timeout_t tout, timeout_t sleep_msec )
{
ostringstream s;
s << ip << ":" << port;
return check(s.str(), tout, sleep_msec);
}
// -----------------------------------------------------------------------------
bool TCPCheck::check( const std::string& _iaddr, timeout_t tout, timeout_t sleep_msec )
{
iaddr = iaddr;
tout_msec = tout;
setResult(false);
ThreadCreator<TCPCheck> t(this, &TCPCheck::check_thread);
t.setCancel(ost::Thread::cancelDeferred);
t.start();
PassiveTimer pt(tout);
while( !pt.checkTime() && t.isRunning() )
msleep(sleep_msec);
if( t.isRunning() ) // !getResult() )
t.stop();
return getResult();
}
// -----------------------------------------------------------------------------
void TCPCheck::check_thread()
{
setResult(false);
try
{
ost::Thread::setException(ost::Thread::throwException);
ost::TCPStream t(iaddr.c_str(),ost::Socket::IPV4,536,true,tout_msec);
setResult(true);
t.disconnect();
}
catch(...){}
}
// -----------------------------------------------------------------------------
......@@ -2,7 +2,7 @@
# This file is part of the UniSet library #
############################################################################
SUBDIRS=Threads ObjectRepository Processes Interfaces Timers IOs Services Various Communications
SUBDIRS=ObjectRepository Processes Interfaces Timers IOs Services Various Communications
include $(top_builddir)/conf/common.mk
......@@ -262,7 +262,7 @@ void ObjectsActivator::work()
try
{
if(orbthr)
thpid = orbthr->getTID();
thpid = orbthr->getId();
else
thpid = getpid();
......
......@@ -874,7 +874,7 @@ void UniSetObject::work()
if( unideb.debugging(Debug::INFO) )
unideb[Debug::INFO] << myname << ": thread processing messages run..." << endl;
if( thr )
msgpid = thr->getTID();
msgpid = thr->getId();
while( isActive() )
{
callback();
......@@ -908,7 +908,7 @@ UniSetTypes::SimpleInfo* UniSetObject::getInfo()
{
if(thr)
{
msgpid = thr->getTID(); // заодно(на всякий) обновим и внутреннюю информацию
msgpid = thr->getId(); // заодно(на всякий) обновим и внутреннюю информацию
info << msgpid;
}
else
......
############################################################################
# This file is part of the UniSet library #
############################################################################
noinst_LTLIBRARIES = libThreads.la
libThreads_la_SOURCES=PosixThread.cc
include $(top_builddir)/conf/setting.mk
/* This file is part of the UniSet project
* Copyright (c) 2002 Free Software Foundation, Inc.
* Copyright (c) 2002 Anton Korbin <ahtoh>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// --------------------------------------------------------------------------
/*! \file
* \author Anthony Korbin
*/
// --------------------------------------------------------------------------
#include "PosixThread.h"
#include <iostream>
using namespace std;
int PosixThread::countThreads = 1;
pthread_rwlock_t PosixThread::lockx = PTHREAD_RWLOCK_INITIALIZER;
pthread_mutex_t PosixThread::mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t PosixThread::condx = PTHREAD_COND_INITIALIZER;
//----------------------------------------------------------------------------------------
PosixThread::PosixThread():
tid(0),
attrPtr(NULL)
{
}
//----------------------------------------------------------------------------------------
PosixThread::~PosixThread()
{
countThreads--;
delete attrPtr;
// pthread_exit( NULL );
}
//----------------------------------------------------------------------------------------
void PosixThread::start( void *args )
{
if( tid )
{
cerr << "startThread: You don't RECREATE thread!" << endl;
return;
}
reinit();
// cout << "Создаю поток..."<< endl;
if( pthread_create( &tid, attrPtr, PosixThread::funcp, args ) == -1 )
{/*throw ThreadNotCreate;*/}
else
{
countThreads++;
pthread_attr_destroy( attrPtr );
}
// cout << "создал поток..."<< endl;
}
//----------------------------------------------------------------------------------------
void PosixThread::stop()
{
unlock();
rwunlock();
tid = 0;
countThreads--;
pthread_exit( NULL );
// cout << "PosixThread: завершил поток"<< endl;
// tid = 0;
// countThreads--;
}
//----------------------------------------------------------------------------------------
void PosixThread::reinit()
{
if (attrPtr != NULL)
delete attrPtr;
attrPtr = new pthread_attr_t;
if( pthread_attr_init( attrPtr ) == -1 )
{/*throw AttrNotInit;*/cerr << "PosixThread(reinit): не удалось..."<< endl;}
}
//----------------------------------------------------------------------------------------
void PosixThread::thrkill( int signo )
{
pthread_kill( tid, signo );
}
//----------------------------------------------------------------------------------------
void PosixThread::setAttr( TAttr attr, int state )
{
switch( attr )
{
case SCOPE:
{
if( state == PTHREAD_SCOPE_SYSTEM )
pthread_attr_setscope( attrPtr, PTHREAD_SCOPE_SYSTEM );
else
pthread_attr_setscope( attrPtr, PTHREAD_SCOPE_PROCESS );
break;
}
case DETACH:
{
if( state == PTHREAD_CREATE_DETACHED )
pthread_attr_setdetachstate( attrPtr, PTHREAD_CREATE_DETACHED );
else
pthread_attr_setdetachstate( attrPtr, PTHREAD_CREATE_JOINABLE );
break;
}
case PRIORITY:
{
struct sched_param sched;
sched.sched_priority = state;
pthread_attr_setschedparam( attrPtr, &sched );
break;
}
default:
{
cerr << "Attr not change. See parameters setAtr(...)" << endl;
}
}
}
//----------------------------------------------------------------------------------------
void PosixThread::setPriority( int priority )
{
setAttr( PosixThread::PRIORITY, priority );
}
//----------------------------------------------------------------------------------------
void* PosixThread::funcp( void *args )
{
PosixThread *pt;
pt = (PosixThread*)args;
pt->work();
pthread_exit(NULL); //???
return 0;
}
//----------------------------------------------------------------------------------------
void PosixThread::readlock( pthread_rwlock_t *lock )
{
pthread_rwlock_rdlock( lock );
}
//----------------------------------------------------------------------------------------
void PosixThread::writelock( pthread_rwlock_t *lock )
{
pthread_rwlock_wrlock( lock );
}
//----------------------------------------------------------------------------------------
void PosixThread::lock( pthread_mutex_t *mute )
{
pthread_mutex_lock( mute );
}
//----------------------------------------------------------------------------------------
void PosixThread::rwunlock( pthread_rwlock_t *lock )
{
pthread_rwlock_unlock( lock );
}
//----------------------------------------------------------------------------------------
void PosixThread::unlock( pthread_mutex_t *mute )
{
pthread_mutex_unlock( mute );
}
//----------------------------------------------------------------------------------------
void PosixThread::wait( pthread_cond_t *cond, pthread_mutex_t *mute )
{
pthread_cond_wait( cond, mute );
}
//----------------------------------------------------------------------------------------
void PosixThread::continueRun( pthread_cond_t *cond )
{
pthread_cond_signal( cond );
}
//----------------------------------------------------------------------------------------
void PosixThread::continueRunAll( pthread_cond_t *cond )
{
pthread_cond_broadcast( cond );
}
//----------------------------------------------------------------------------------------
......@@ -58,6 +58,11 @@ clock_ticks(sysconf(_SC_CLK_TCK))
}
//------------------------------------------------------------------------------
PassiveTimer::~PassiveTimer()
{
}
//------------------------------------------------------------------------------
bool PassiveTimer::checkTime()
{
// printf("times=%d, act=%d\n",times(0),timeAct);
......@@ -117,4 +122,3 @@ clock_t PassiveTimer::times()
struct tms tm;
return ::times(&tm);
}
......@@ -3,8 +3,8 @@
############################################################################
noinst_LTLIBRARIES = libVarious.la
libVarious_la_CPPFLAGS = $(SIGC_CFLAGS)
libVarious_la_LIBADD = $(SIGC_LIBS)
libVarious_la_CPPFLAGS = $(SIGC_CFLAGS) $(COMCPP_CFLAGS)
libVarious_la_LIBADD = $(SIGC_LIBS) $(COMCPP_LIBS)
libVarious_la_SOURCES = DebugStream.cc Debug.cc UniXML.cc MessageType.cc Configuration.cc SystemGuard.cc TextIndex.cc \
Restorer_XML.cc \
NCRestorer.cc NCRestorer_XML.cc \
......
......@@ -347,7 +347,7 @@ SimpleInfo* SystemGuard::getInfo()
SimpleInfo_var si = ObjectsManager::getInfo();
info << si->info;
if( thr )
info << "\texTID= " << thr->getTID();
info << "\texTID= " << thr->getId();
else
info << "\texpid= " << expid;
......
......@@ -4,7 +4,7 @@
SUBDIRS=JrnTests
noinst_PROGRAMS = passivetimer hourglass delaytimer unixml ui umutex conftest iterator_test sscanf_hex calibration
noinst_PROGRAMS = passivetimer hourglass delaytimer unixml ui umutex conftest iterator_test sscanf_hex calibration threadtst
passivetimer_SOURCES = passivetimer.cc
passivetimer_LDADD = $(top_builddir)/lib/libUniSet.la
......@@ -31,8 +31,8 @@ ui_LDADD = $(top_builddir)/lib/libUniSet.la
ui_CPPFLAGS = -I$(top_builddir)/include
umutex_SOURCES = umutex.cc
umutex_LDADD = $(top_builddir)/lib/libUniSet.la
umutex_CPPFLAGS = -I$(top_builddir)/include
umutex_LDADD = $(top_builddir)/lib/libUniSet.la $(COMCPP_LIBS)
umutex_CPPFLAGS = -I$(top_builddir)/include $(COMCPP_CFLAGS)
conftest_SOURCES = conftest.cc
conftest_LDADD = $(top_builddir)/lib/libUniSet.la
......@@ -44,6 +44,10 @@ calibration_SOURCES = calibration.cc
calibration_LDADD = $(top_builddir)/lib/libUniSet.la ${SIGC_LIBS}
calibration_CPPFLAGS = -I$(top_builddir)/include ${SIGC_CFLAGS}
threadtst_SOURCES = threadtst.cc
threadtst_LDADD = $(top_builddir)/lib/libUniSet.la ${SIGC_LIBS} $(COMCPP_LIBS)
threadtst_CPPFLAGS = -I$(top_builddir)/include ${SIGC_CFLAGS} $(COMCPP_CFLAGS)
include $(top_builddir)/conf/setting.mk
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment