- Pretty-indenting code
git-svn-id: svn://svn.gna.org/svn/sgpemv2/trunk@674 3ecf2c5c-341e-0410-92b4-d18e462d057c
This commit is contained in:
parent
7aecc910ba
commit
6b27a8461b
94 changed files with 3073 additions and 3066 deletions
|
@ -21,7 +21,7 @@
|
|||
// The idea of this file is to provide a static function to execute
|
||||
// when the plugin (this library) is loaded. Thus the name "hook".
|
||||
|
||||
// For the moment, instead of a function hook to be called by the
|
||||
// For the moment, instead of a function hook to be called by the
|
||||
// libbackend.so module, we have a static PythonPolicyManager object.
|
||||
// This is a risk.
|
||||
#warning FIXME : this code is quite a bad idea. Replace me with \
|
||||
|
@ -33,24 +33,25 @@
|
|||
#include "config.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#define SG_CONSTRUCTOR __attribute__ ((constructor))
|
||||
#define SG_DESTRUCTOR __attribute__ ((destructor))
|
||||
#define _libpyloader_LTX__global_pm (_global_pm);
|
||||
|
||||
PolicyManager* _global_pm = NULL;
|
||||
PolicyManager* _global_pm = NULL;
|
||||
|
||||
void SG_DLLEXPORT SG_CONSTRUCTOR hook_ctor(void)
|
||||
{
|
||||
_global_pm = PythonPolicyManager::get_instance();
|
||||
}
|
||||
void SG_DLLEXPORT SG_CONSTRUCTOR hook_ctor(void)
|
||||
{
|
||||
_global_pm = PythonPolicyManager::get_instance();
|
||||
}
|
||||
|
||||
void SG_DLLEXPORT SG_DESTRUCTOR hook_dtor(void)
|
||||
{
|
||||
delete _global_pm;
|
||||
}
|
||||
void SG_DLLEXPORT SG_DESTRUCTOR hook_dtor(void)
|
||||
{
|
||||
delete _global_pm;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -31,19 +31,19 @@ using namespace std;
|
|||
// *strong* exception checking / handling!
|
||||
|
||||
PythonPolicy::PythonPolicy(const char* name)
|
||||
: _upolicy_dict(NULL), _adapter(NULL), _name(name)
|
||||
: _upolicy_dict(NULL), _adapter(NULL), _name(name)
|
||||
{
|
||||
PyObject* pLoadmeStr = PyString_FromString(name);
|
||||
PyObject* pUserPolicyModule = PyImport_Import(pLoadmeStr);
|
||||
Py_DECREF(pLoadmeStr);
|
||||
|
||||
if( !pUserPolicyModule )
|
||||
|
||||
if( !pUserPolicyModule )
|
||||
{
|
||||
PyErr_Print(); // Error in import
|
||||
// FIXME : don't exit abruptly, but fall back gracefully
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
|
||||
// Dictionary with defined ``symbols'' for .pyc file
|
||||
_upolicy_dict = PyModule_GetDict(pUserPolicyModule);
|
||||
assert(_upolicy_dict);
|
||||
|
@ -55,11 +55,11 @@ PythonPolicy::PythonPolicy(const char* name)
|
|||
assert(pScriptAdapterModule);
|
||||
PyObject* pAdapterDict = PyModule_GetDict(pScriptAdapterModule);
|
||||
assert(pAdapterDict);
|
||||
|
||||
|
||||
// Now takes the user-defined policy class from pUserPolicyDict
|
||||
PyObject* pPolicyClass = PyDict_GetItemString(_upolicy_dict, name);
|
||||
assert(pPolicyClass); // FIXME needs stricter checking and exception throwing
|
||||
|
||||
|
||||
// Creates a new object of type ScriptAdapter :
|
||||
// takes init function from ScriptAdapter class
|
||||
PyObject* pAdapterClass = PyDict_GetItemString(pAdapterDict, "ScriptAdapter");
|
||||
|
@ -80,10 +80,10 @@ PythonPolicy::~PythonPolicy()
|
|||
{
|
||||
if(_adapter) Py_DECREF(_adapter);
|
||||
|
||||
// We keep this alive until dtor time, because
|
||||
// the user may have defined some static global-space
|
||||
// variables and they make use of them.
|
||||
if(_upolicy_dict) Py_DECREF(_upolicy_dict);
|
||||
// We keep this alive until dtor time, because
|
||||
// the user may have defined some static global-space
|
||||
// variables and they make use of them.
|
||||
if(_upolicy_dict) Py_DECREF(_upolicy_dict);
|
||||
}
|
||||
|
||||
|
||||
|
@ -102,19 +102,19 @@ PythonPolicy::sort_queue() const throw(UserInterruptException)
|
|||
{
|
||||
PyObject* pMethodName = PyString_FromString("async_sort_queue");
|
||||
PyObject* retval = PyObject_CallMethodObjArgs(_adapter, pMethodName, NULL, NULL);
|
||||
|
||||
|
||||
// Do minimal debugging
|
||||
if(!retval) PyErr_Print();
|
||||
else Py_DECREF(retval);
|
||||
|
||||
|
||||
Py_DECREF(pMethodName);
|
||||
|
||||
|
||||
wait_unlock();
|
||||
}
|
||||
|
||||
|
||||
Glib::ustring
|
||||
PythonPolicy::get_description() const
|
||||
PythonPolicy::get_description() const
|
||||
{
|
||||
return _name;
|
||||
}
|
||||
|
@ -127,13 +127,13 @@ PythonPolicy::get_name() const
|
|||
}
|
||||
|
||||
bool
|
||||
PythonPolicy::is_pre_emptive() const throw(UserInterruptException)
|
||||
PythonPolicy::is_pre_emptive() const throw(UserInterruptException)
|
||||
{
|
||||
PyObject* retval = PyObject_CallMethod(_adapter, "async_is_preemptive", NULL);
|
||||
Py_DECREF(retval);
|
||||
|
||||
|
||||
wait_unlock();
|
||||
|
||||
|
||||
// Parse return value stored in global Python object
|
||||
retval = PyObject_CallMethod(_adapter, "get_return_value", NULL);
|
||||
assert(retval);
|
||||
|
@ -144,13 +144,13 @@ PythonPolicy::is_pre_emptive() const throw(UserInterruptException)
|
|||
|
||||
|
||||
int
|
||||
PythonPolicy::get_time_slice() const throw(UserInterruptException)
|
||||
PythonPolicy::get_time_slice() const throw(UserInterruptException)
|
||||
{
|
||||
PyObject* retval = PyObject_CallMethod(_adapter, "async_get_time_slice", NULL);
|
||||
Py_DECREF(retval);
|
||||
|
||||
|
||||
wait_unlock();
|
||||
|
||||
|
||||
// Parse return value stored in global Python object
|
||||
retval = PyObject_CallMethod(_adapter, "get_return_value", NULL);
|
||||
assert(retval);
|
||||
|
@ -161,13 +161,13 @@ PythonPolicy::get_time_slice() const throw(UserInterruptException)
|
|||
}
|
||||
|
||||
policy_sorts_type
|
||||
PythonPolicy::wants() const throw(UserInterruptException)
|
||||
PythonPolicy::wants() const throw(UserInterruptException)
|
||||
{
|
||||
PyObject* retval = PyObject_CallMethod(_adapter, "async_wants", NULL);
|
||||
Py_DECREF(retval);
|
||||
|
||||
|
||||
wait_unlock();
|
||||
|
||||
|
||||
// Parse return value stored in global Python object
|
||||
retval = PyObject_CallMethod(_adapter, "get_return_value", NULL);
|
||||
assert(retval);
|
||||
|
@ -181,39 +181,39 @@ PythonPolicy::wants() const throw(UserInterruptException)
|
|||
else
|
||||
return policy_sorts_processes;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PythonPolicy::wait_unlock() const throw(UserInterruptException)
|
||||
{
|
||||
PyThreadState* _save;
|
||||
int i = 0; // We give the sort_queue() three seconds max time, then...
|
||||
// we shot it stone dead! Bang.
|
||||
// we shot it stone dead! Bang.
|
||||
|
||||
bool still_locked;
|
||||
do
|
||||
do
|
||||
{
|
||||
Py_UNBLOCK_THREADS;
|
||||
usleep(WAIT_FOR); // hack'a'ton! magggggiccc nummmbeeerrrrrs!!
|
||||
Py_BLOCK_THREADS;
|
||||
|
||||
PyObject* retval = PyObject_CallMethod(_adapter, "mutex_test_lock", NULL);
|
||||
assert(retval);
|
||||
still_locked = PyObject_IsTrue(retval);
|
||||
Py_DECREF(retval);
|
||||
|
||||
if(i++ > 12) /* waits for WAIT_FOR * 12 microseconds == 3 secs */
|
||||
{
|
||||
PyThreadState_Clear(_save);
|
||||
// As the API documentation says, the caller of PyEval_RestoreThread
|
||||
// should NOT possess the interpreter lock
|
||||
Py_UNBLOCK_THREADS;
|
||||
usleep(WAIT_FOR); // hack'a'ton! magggggiccc nummmbeeerrrrrs!!
|
||||
Py_BLOCK_THREADS;
|
||||
|
||||
PyObject* retval = PyObject_CallMethod(_adapter, "mutex_test_lock", NULL);
|
||||
assert(retval);
|
||||
still_locked = PyObject_IsTrue(retval);
|
||||
Py_DECREF(retval);
|
||||
PyEval_RestoreThread(_save);
|
||||
|
||||
if(i++ > 12) /* waits for WAIT_FOR * 12 microseconds == 3 secs */
|
||||
{
|
||||
PyThreadState_Clear(_save);
|
||||
// As the API documentation says, the caller of PyEval_RestoreThread
|
||||
// should NOT possess the interpreter lock
|
||||
Py_UNBLOCK_THREADS;
|
||||
PyEval_RestoreThread(_save);
|
||||
|
||||
|
||||
throw UserInterruptException("User-defined policy is "
|
||||
"taking too long to terminate.");
|
||||
}
|
||||
}
|
||||
throw UserInterruptException("User-defined policy is "
|
||||
"taking too long to terminate.");
|
||||
}
|
||||
}
|
||||
while(still_locked);
|
||||
|
||||
// What we should really do here:
|
||||
|
@ -226,9 +226,9 @@ PythonPolicy::wait_unlock() const throw(UserInterruptException)
|
|||
...if he has, break
|
||||
...else:
|
||||
if the global lock is set:
|
||||
stay in this loop
|
||||
else:
|
||||
all's went okay, can exit loop
|
||||
stay in this loop
|
||||
else:
|
||||
all's went okay, can exit loop
|
||||
} */
|
||||
|
||||
}
|
||||
|
|
|
@ -37,46 +37,46 @@ namespace sgpem
|
|||
class PythonPolicyManager;
|
||||
class UserInterruptException;
|
||||
|
||||
/** \brief A specialization of abstract class Policy
|
||||
/** \brief A specialization of abstract class Policy
|
||||
|
||||
This class represents a policy written in Python. Its methods interact with Python interpreter.
|
||||
See the documentation of class Policy for more detailed informations.
|
||||
*/
|
||||
This class represents a policy written in Python. Its methods interact with Python interpreter.
|
||||
See the documentation of class Policy for more detailed informations.
|
||||
*/
|
||||
class SG_DLLEXPORT PythonPolicy : public Policy
|
||||
{
|
||||
public:
|
||||
PythonPolicy(const char* name);
|
||||
virtual ~PythonPolicy();
|
||||
|
||||
/**
|
||||
Calls the method \c async_configure
|
||||
*/
|
||||
void configure() throw(UserInterruptException);
|
||||
/**
|
||||
Calls the method \c async_configure
|
||||
*/
|
||||
void configure() throw(UserInterruptException);
|
||||
|
||||
/**
|
||||
Calls the method \c async_sort_queue
|
||||
Calls the method \c async_sort_queue
|
||||
*/
|
||||
void sort_queue() const throw(UserInterruptException);
|
||||
void sort_queue() const throw(UserInterruptException);
|
||||
|
||||
/**
|
||||
\returns A textual description of this policy.
|
||||
\returns A textual description of this policy.
|
||||
*/
|
||||
Glib::ustring get_description() const;
|
||||
Glib::ustring get_description() const;
|
||||
|
||||
Glib::ustring get_name() const;
|
||||
Glib::ustring get_name() const;
|
||||
|
||||
/**
|
||||
\returns \c TRUE if the policy is preemptive.
|
||||
\returns \c FALSE if the policy is not preemptive.
|
||||
\returns \c TRUE if the policy is preemptive.
|
||||
\returns \c FALSE if the policy is not preemptive.
|
||||
*/
|
||||
bool is_pre_emptive() const throw(UserInterruptException);
|
||||
bool is_pre_emptive() const throw(UserInterruptException);
|
||||
|
||||
/**
|
||||
\returns The integer value of its time-slice.
|
||||
\returns The integer value of its time-slice.
|
||||
*/
|
||||
int get_time_slice() const throw(UserInterruptException);
|
||||
int get_time_slice() const throw(UserInterruptException);
|
||||
|
||||
policy_sorts_type wants() const throw(UserInterruptException);
|
||||
policy_sorts_type wants() const throw(UserInterruptException);
|
||||
|
||||
void activate()
|
||||
{
|
||||
|
|
|
@ -45,15 +45,15 @@ using std::endl;
|
|||
struct pol_dirs_concat : public std::unary_function<void, const Glib::ustring&>
|
||||
{
|
||||
public:
|
||||
pol_dirs_concat(Glib::ustring& cat) : _cat(cat) {}
|
||||
void operator()(const Glib::ustring& add)
|
||||
{
|
||||
// Please note that this string will end finishing with
|
||||
// and additional ","!
|
||||
_cat += "'" + add + "', ";
|
||||
}
|
||||
pol_dirs_concat(Glib::ustring& cat) : _cat(cat) {}
|
||||
void operator()(const Glib::ustring& add)
|
||||
{
|
||||
// Please note that this string will end finishing with
|
||||
// and additional ","!
|
||||
_cat += "'" + add + "', ";
|
||||
}
|
||||
private:
|
||||
Glib::ustring& _cat;
|
||||
Glib::ustring& _cat;
|
||||
};
|
||||
|
||||
|
||||
|
@ -63,7 +63,7 @@ PythonPolicyManager* PythonPolicyManager::_instance = NULL;
|
|||
|
||||
|
||||
PythonPolicyManager::PythonPolicyManager()
|
||||
: _initialized(false)
|
||||
: _initialized(false)
|
||||
{
|
||||
PyEval_InitThreads();
|
||||
}
|
||||
|
@ -94,31 +94,31 @@ PythonPolicyManager::get_instance()
|
|||
void
|
||||
PythonPolicyManager::init()
|
||||
{
|
||||
if(_initialized)
|
||||
// No-op
|
||||
return;
|
||||
|
||||
if(_initialized)
|
||||
// No-op
|
||||
return;
|
||||
|
||||
Py_Initialize();
|
||||
_initialized = true;
|
||||
|
||||
// The following lines are ugly, but necessary if we use
|
||||
|
||||
// The following lines are ugly, but necessary if we use
|
||||
// non-standard installation directories. Theoretically,
|
||||
// it should be up to the user to set correct
|
||||
// environment variables.
|
||||
// it should be up to the user to set correct
|
||||
// environment variables.
|
||||
// FIXME: find better way to achieve this.
|
||||
|
||||
|
||||
GlobalPreferences& prefs = GlobalPreferences::get_instance();
|
||||
Glib::ustring importdirs = "import sys\n"
|
||||
"sys.path[:0] = [ ";
|
||||
Glib::ustring importdirs = "import sys\n"
|
||||
"sys.path[:0] = [ ";
|
||||
for_each(prefs.policies_dir_begin(),
|
||||
prefs.policies_dir_end(),
|
||||
pol_dirs_concat(importdirs));
|
||||
prefs.policies_dir_end(),
|
||||
pol_dirs_concat(importdirs));
|
||||
importdirs += " '" SHAREDIR "' ]\n";
|
||||
|
||||
PyRun_SimpleString(importdirs.c_str());
|
||||
|
||||
// Okay, here we go.
|
||||
// Black magic at work.
|
||||
// Black magic at work.
|
||||
|
||||
collect_policies();
|
||||
}
|
||||
|
@ -141,30 +141,30 @@ PythonPolicyManager::collect_policies()
|
|||
Glib::Dir dir(dir_it->c_str());
|
||||
|
||||
cout << "Opening directory " << *dir_it << "..." << endl;
|
||||
|
||||
|
||||
for(Glib::DirIterator file_it = dir.begin(); file_it != dir.end(); ++file_it)
|
||||
{
|
||||
cout << "\tChecking if " << *file_it << " is a Python script... " << endl;
|
||||
|
||||
|
||||
Glib::PatternSpec dot_py("*.py");
|
||||
|
||||
if(dot_py.match(*file_it))
|
||||
{
|
||||
cout << "\t\tIt is.\n";
|
||||
|
||||
//strip extension
|
||||
std::string policy_name = (*file_it).substr(0, (*file_it).size() - 3);
|
||||
|
||||
PythonPolicy *pypolicy = new PythonPolicy(policy_name.c_str());
|
||||
|
||||
_policies.push_back(pypolicy);
|
||||
//strip extension
|
||||
std::string policy_name = (*file_it).substr(0, (*file_it).size() - 3);
|
||||
|
||||
//FIXME remove me when get_policy is dropped
|
||||
if(policy_name == "fcfs")
|
||||
{
|
||||
_python_policy = pypolicy;
|
||||
PoliciesGatekeeper::get_instance().activate_policy(&History::get_instance(), pypolicy);
|
||||
}
|
||||
PythonPolicy *pypolicy = new PythonPolicy(policy_name.c_str());
|
||||
|
||||
_policies.push_back(pypolicy);
|
||||
|
||||
//FIXME remove me when get_policy is dropped
|
||||
if(policy_name == "fcfs")
|
||||
{
|
||||
_python_policy = pypolicy;
|
||||
PoliciesGatekeeper::get_instance().activate_policy(&History::get_instance(), pypolicy);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,22 +61,22 @@ namespace sgpem
|
|||
|
||||
std::vector<Policy*> get_avail_policies();
|
||||
|
||||
/** \brief Returns the singleton instance of
|
||||
* PythonPolicyManager.
|
||||
*
|
||||
* Please note that the first time you'll request
|
||||
* it, it will be still uninitialized.
|
||||
* @see init()
|
||||
*/
|
||||
static PythonPolicyManager* const get_instance();
|
||||
|
||||
/** \brief Returns the singleton instance of
|
||||
* PythonPolicyManager.
|
||||
*
|
||||
* Please note that the first time you'll request
|
||||
* it, it will be still uninitialized.
|
||||
* @see init()
|
||||
*/
|
||||
static PythonPolicyManager* const get_instance();
|
||||
|
||||
protected:
|
||||
/** The selected and active PyhonPolicy object. */
|
||||
PythonPolicyManager();
|
||||
~PythonPolicyManager();
|
||||
|
||||
void collect_policies();
|
||||
|
||||
|
||||
PythonPolicy* _python_policy;
|
||||
|
||||
private:
|
||||
|
|
|
@ -39,88 +39,93 @@
|
|||
// FIXME: Eeeeh? Why does this work without explicit namespace resolving?
|
||||
// Is there some using declaration in included HEADERS?? Aaaaagh!
|
||||
|
||||
class TestPythonPolicyManager : public PythonPolicyManager {
|
||||
class TestPythonPolicyManager : public PythonPolicyManager
|
||||
{
|
||||
public:
|
||||
void test_init(const char* policy_name) {
|
||||
void test_init(const char* policy_name)
|
||||
{
|
||||
init();
|
||||
_python_policy = new PythonPolicy(policy_name);
|
||||
|
||||
|
||||
}
|
||||
|
||||
Policy& get_policy() {
|
||||
Policy& get_policy()
|
||||
{
|
||||
return *_python_policy;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char** argv) {
|
||||
using namespace sgpem;
|
||||
using namespace std;
|
||||
main(int argc, char** argv)
|
||||
{
|
||||
using namespace sgpem;
|
||||
using namespace std;
|
||||
|
||||
int successes = 0;
|
||||
int successes = 0;
|
||||
|
||||
if(argc != 2) {
|
||||
std::cout << "[EE] Usage:\n\t" << argv[0] <<
|
||||
" path/to/uninstalled/policies" << std::endl;
|
||||
exit(-1);
|
||||
}
|
||||
else
|
||||
// Add argv[1] as the directory to search for uninstalled policies
|
||||
sgpem::GlobalPreferences::get_instance().add_policies_dir(argv[1]);
|
||||
if(argc != 2)
|
||||
{
|
||||
std::cout << "[EE] Usage:\n\t" << argv[0] <<
|
||||
" path/to/uninstalled/policies" << std::endl;
|
||||
exit(-1);
|
||||
}
|
||||
else
|
||||
// Add argv[1] as the directory to search for uninstalled policies
|
||||
sgpem::GlobalPreferences::get_instance().add_policies_dir(argv[1]);
|
||||
|
||||
// Self-register itself to Scheduler, however we don't care about it
|
||||
TestPythonPolicyManager polman;
|
||||
// Self-register itself to Scheduler, however we don't care about it
|
||||
TestPythonPolicyManager polman;
|
||||
|
||||
try
|
||||
{
|
||||
polman.test_init("python_loader_configure");
|
||||
polman.get_policy().configure();
|
||||
}
|
||||
catch(UserInterruptException e)
|
||||
{
|
||||
cout << "configure: Caught UserInterruptException" << endl;
|
||||
successes++;
|
||||
}
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
polman.test_init("python_loader_is_preemptive");
|
||||
polman.get_policy().is_pre_emptive();
|
||||
}
|
||||
catch(UserInterruptException e)
|
||||
{
|
||||
cout << "is_preemptive: Caught UserInterruptException" << endl;
|
||||
successes++;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
polman.test_init("python_loader_get_time_slice");
|
||||
polman.get_policy().get_time_slice();
|
||||
}
|
||||
catch(UserInterruptException e)
|
||||
{
|
||||
cout << "get_time_slice: Caught UserInterruptException" << endl;
|
||||
successes++;
|
||||
}
|
||||
try
|
||||
{
|
||||
polman.test_init("python_loader_configure");
|
||||
polman.get_policy().configure();
|
||||
}
|
||||
catch(UserInterruptException e)
|
||||
{
|
||||
cout << "configure: Caught UserInterruptException" << endl;
|
||||
successes++;
|
||||
}
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
SchedulableQueue sl;
|
||||
polman.test_init("python_loader_sort_queue");
|
||||
polman.get_policy().sort_queue();
|
||||
}
|
||||
catch(UserInterruptException e)
|
||||
{
|
||||
cout << "sort_queue: Caught UserInterruptException" << endl;
|
||||
successes++;
|
||||
}
|
||||
try
|
||||
{
|
||||
polman.test_init("python_loader_is_preemptive");
|
||||
polman.get_policy().is_pre_emptive();
|
||||
}
|
||||
catch(UserInterruptException e)
|
||||
{
|
||||
cout << "is_preemptive: Caught UserInterruptException" << endl;
|
||||
successes++;
|
||||
}
|
||||
|
||||
cout << "Result: catched " << successes
|
||||
<< " exceptions out of 4." << endl;
|
||||
try
|
||||
{
|
||||
polman.test_init("python_loader_get_time_slice");
|
||||
polman.get_policy().get_time_slice();
|
||||
}
|
||||
catch(UserInterruptException e)
|
||||
{
|
||||
cout << "get_time_slice: Caught UserInterruptException" << endl;
|
||||
successes++;
|
||||
}
|
||||
|
||||
exit(0);
|
||||
|
||||
try
|
||||
{
|
||||
SchedulableQueue sl;
|
||||
polman.test_init("python_loader_sort_queue");
|
||||
polman.get_policy().sort_queue();
|
||||
}
|
||||
catch(UserInterruptException e)
|
||||
{
|
||||
cout << "sort_queue: Caught UserInterruptException" << endl;
|
||||
successes++;
|
||||
}
|
||||
|
||||
cout << "Result: catched " << successes
|
||||
<< " exceptions out of 4." << endl;
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
// The idea of this file is to provide a static function to execute
|
||||
// when the plugin (this library) is loaded. Thus the name "hook".
|
||||
|
||||
// For the moment, instead of a function hook to be called by the
|
||||
// For the moment, instead of a function hook to be called by the
|
||||
// libbackend.so module, we have a static PythonPolicyManager object.
|
||||
// This is a risk.
|
||||
#warning FIXME : this code is quite a bad idea. Replace me with \
|
||||
|
@ -29,7 +29,8 @@
|
|||
therein. See "info libtool": "dlopened modules"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include "config.h"
|
||||
|
@ -37,13 +38,11 @@ extern "C" {
|
|||
#define SG_CONSTRUCTOR __attribute__ ((constructor))
|
||||
#define SG_DESTRUCTOR __attribute__ ((destructor))
|
||||
|
||||
void SG_DLLEXPORT SG_CONSTRUCTOR hook_ctor(void)
|
||||
{
|
||||
}
|
||||
void SG_DLLEXPORT SG_CONSTRUCTOR hook_ctor(void)
|
||||
{}
|
||||
|
||||
void SG_DLLEXPORT SG_DESTRUCTOR hook_dtor(void)
|
||||
{
|
||||
}
|
||||
void SG_DLLEXPORT SG_DESTRUCTOR hook_dtor(void)
|
||||
{}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue