added: a deadlock counter to Synchro class
now we can use Lock() more than one in the same thread and next Unlock() will recognize it sample: Lock(); // first lock -- resources locked Lock(); // second lock -- skipped (counter incremented) ... Unlock(); // first unlock -- skipped (because counter greater than zero) Unlock(); // second unlock -- actually unlocking git-svn-id: svn://ttmath.org/publicrep/winix/trunk@830 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
parent
1da1eef768
commit
fc33b4f882
|
@ -139,8 +139,6 @@ void Job::DoJob(PT::Space & job)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// !! FIXME plugin.Call() can log messages
|
|
||||||
// we need Lock/Unlock mechanism there
|
|
||||||
PluginRes res = plugin.Call((Session*)0, WINIX_JOB, &job);
|
PluginRes res = plugin.Call((Session*)0, WINIX_JOB, &job);
|
||||||
|
|
||||||
if( res.res_true == 0 )
|
if( res.res_true == 0 )
|
||||||
|
|
|
@ -98,6 +98,21 @@ void Plugin::SetSessionManager(SessionManager * psession_manager)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void Plugin::Lock()
|
||||||
|
{
|
||||||
|
if( synchro )
|
||||||
|
synchro->Lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Plugin::Unlock()
|
||||||
|
{
|
||||||
|
if( synchro )
|
||||||
|
synchro->Unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool Plugin::SetPointers(PluginInfo & info)
|
bool Plugin::SetPointers(PluginInfo & info)
|
||||||
{
|
{
|
||||||
|
@ -105,7 +120,11 @@ bool Plugin::SetPointers(PluginInfo & info)
|
||||||
bool res = (db && config && cur && system && functions && templates && synchro && session_manager);
|
bool res = (db && config && cur && system && functions && templates && synchro && session_manager);
|
||||||
|
|
||||||
if( !res )
|
if( !res )
|
||||||
|
{
|
||||||
|
Lock();
|
||||||
log << log1 << "Plugin: cannot call a function - some of the winix pointers are null" << logend;
|
log << log1 << "Plugin: cannot call a function - some of the winix pointers are null" << logend;
|
||||||
|
Unlock();
|
||||||
|
}
|
||||||
|
|
||||||
info.db = db;
|
info.db = db;
|
||||||
info.config = config;
|
info.config = config;
|
||||||
|
@ -145,7 +164,8 @@ void Plugin::LoadPlugin(const std::string & filename)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// we don't have to use Lock() here because plusings are read
|
||||||
|
// before threads are started
|
||||||
void * Plugin::LoadInitFun(const char * filename, Fun1 & fun_init)
|
void * Plugin::LoadInitFun(const char * filename, Fun1 & fun_init)
|
||||||
{
|
{
|
||||||
void * p = dlopen(filename, RTLD_NOW | RTLD_LOCAL);
|
void * p = dlopen(filename, RTLD_NOW | RTLD_LOCAL);
|
||||||
|
@ -265,7 +285,11 @@ void Plugin::Call(Session * ses, int message, Slots::iterator & slot, PluginInfo
|
||||||
if( !slot->second.is_running )
|
if( !slot->second.is_running )
|
||||||
{
|
{
|
||||||
if( config->log_plugin_call )
|
if( config->log_plugin_call )
|
||||||
|
{
|
||||||
|
Lock();
|
||||||
log << log1 << "Plugin: calling plugin id: " << slot->second.index << ", message: " << message << logend;
|
log << log1 << "Plugin: calling plugin id: " << slot->second.index << ", message: " << message << logend;
|
||||||
|
Unlock();
|
||||||
|
}
|
||||||
|
|
||||||
slot->second.is_running = true;
|
slot->second.is_running = true;
|
||||||
|
|
||||||
|
@ -278,15 +302,21 @@ void Plugin::Call(Session * ses, int message, Slots::iterator & slot, PluginInfo
|
||||||
slot->second.is_running = false;
|
slot->second.is_running = false;
|
||||||
|
|
||||||
if( config->log_plugin_call )
|
if( config->log_plugin_call )
|
||||||
|
{
|
||||||
|
Lock();
|
||||||
log << log1 << "Plugin: returning from plugin id: " << slot->second.index << ", message: " << message
|
log << log1 << "Plugin: returning from plugin id: " << slot->second.index << ", message: " << message
|
||||||
<< ", result: " << (info.res? "true" : "false") << logend;
|
<< ", result: " << (info.res? "true" : "false") << logend;
|
||||||
|
Unlock();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
Lock();
|
||||||
log << log1 << "Plugin: id: " << slot->second.index
|
log << log1 << "Plugin: id: " << slot->second.index
|
||||||
<< ", message: " << message
|
<< ", message: " << message
|
||||||
<< ", recurrences are not allowed" << logend;
|
<< ", recurrences are not allowed" << logend;
|
||||||
|
Unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -430,10 +460,10 @@ size_t Plugin::Size()
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
!! IMPROVE ME
|
!! IMPROVE ME
|
||||||
Assign() can work only if other threads are not started
|
Assign() can work only if other threads are not started
|
||||||
we can add some barrier/flag so when other threads starts
|
we can add some barrier/flag so when other threads starts
|
||||||
then we cannot use Assign() method
|
then we cannot use Assign() method
|
||||||
*/
|
*/
|
||||||
void Plugin::Assign(int message, Fun1 fun1)
|
void Plugin::Assign(int message, Fun1 fun1)
|
||||||
{
|
{
|
||||||
|
|
|
@ -225,19 +225,20 @@ private:
|
||||||
Synchro * synchro;
|
Synchro * synchro;
|
||||||
SessionManager * session_manager;
|
SessionManager * session_manager;
|
||||||
|
|
||||||
std::wstring temp_path;
|
std::wstring temp_path; // used when loading plugins
|
||||||
|
std::string afilename;
|
||||||
|
|
||||||
Plugins plugins;
|
Plugins plugins;
|
||||||
|
|
||||||
typedef std::multimap<int, Slot> Slots;
|
typedef std::multimap<int, Slot> Slots;
|
||||||
Slots slots;
|
Slots slots;
|
||||||
|
|
||||||
std::string afilename;
|
|
||||||
|
|
||||||
void * LoadInitFun(const char * filename, Fun1 & fun_init);
|
void * LoadInitFun(const char * filename, Fun1 & fun_init);
|
||||||
void Call(Session * ses, int message, Slots::iterator & slot, PluginInfo & info);
|
void Call(Session * ses, int message, Slots::iterator & slot, PluginInfo & info);
|
||||||
|
|
||||||
bool SetPointers(PluginInfo & info);
|
bool SetPointers(PluginInfo & info);
|
||||||
|
void Lock();
|
||||||
|
void Unlock();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,31 +2,53 @@
|
||||||
* This file is a part of Winix
|
* This file is a part of Winix
|
||||||
* and is not publicly distributed
|
* and is not publicly distributed
|
||||||
*
|
*
|
||||||
* Copyright (c) 2010, Tomasz Sowa
|
* Copyright (c) 2010-2012, Tomasz Sowa
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "synchro.h"
|
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include "synchro.h"
|
||||||
|
|
||||||
|
|
||||||
Synchro::Synchro() : mutex(PTHREAD_MUTEX_INITIALIZER)
|
Synchro::Synchro() : mutex(PTHREAD_MUTEX_INITIALIZER)
|
||||||
{
|
{
|
||||||
was_stop_signal = false;
|
was_stop_signal = false;
|
||||||
|
ref = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool Synchro::Lock()
|
bool Synchro::Lock()
|
||||||
{
|
{
|
||||||
return pthread_mutex_lock(&mutex) == 0;
|
int res = pthread_mutex_lock(&mutex);
|
||||||
|
|
||||||
|
if( res == EDEADLK )
|
||||||
|
{
|
||||||
|
// Lock() method in this thread was called before
|
||||||
|
ref += 1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ref = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Synchro::Unlock()
|
void Synchro::Unlock()
|
||||||
{
|
{
|
||||||
pthread_mutex_unlock(&mutex);
|
if( ref > 0 )
|
||||||
|
{
|
||||||
|
ref -= 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pthread_mutex_unlock(&mutex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* This file is a part of Winix
|
* This file is a part of Winix
|
||||||
* and is not publicly distributed
|
* and is not publicly distributed
|
||||||
*
|
*
|
||||||
* Copyright (c) 2010, Tomasz Sowa
|
* Copyright (c) 2010-2012, Tomasz Sowa
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
@ -28,6 +28,13 @@ struct Synchro
|
||||||
|
|
||||||
bool Lock();
|
bool Lock();
|
||||||
void Unlock();
|
void Unlock();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
// deadlock counter
|
||||||
|
// we can call Lock() more than one in the same thread
|
||||||
|
int ref;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue