Changeset 2242

Show
Ignore:
Timestamp:
07/03/07 09:39:37 (1 year ago)
Author:
abaumann
Message:

Fix a locking bug I introduced. Also adds extra tracing and error handling.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • plugins/python-module/src/python_module.c

    r2230 r2242  
    325325static void *pm_initialize(OSyncPlugin *plugin, OSyncPluginInfo *info, OSyncError **error) 
    326326{ 
     327        osync_trace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, plugin, info, error); 
    327328        MemberData *data = g_malloc0(sizeof(MemberData)); 
    328329        char *modulename; 
     
    370371 
    371372        PyGILState_Release(pystate); 
     373        osync_trace(TRACE_EXIT, "%s", __func__); 
    372374        return data; 
    373375 
     
    377379        PyGILState_Release(pystate); 
    378380        free(data); 
     381        osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error)); 
    379382        return NULL; 
    380383} 
     
    382385static osync_bool pm_discover(void *data_in, OSyncPluginInfo *info, OSyncError **error) 
    383386{ 
     387        osync_trace(TRACE_ENTRY, "%s(%p, %p, %p)", __func__, data_in, info, error); 
     388 
    384389        MemberData *data = data_in; 
    385390 
     
    397402        Py_DECREF(ret); 
    398403        PyGILState_Release(pystate); 
     404        osync_trace(TRACE_EXIT, "%s", __func__); 
    399405        return TRUE; 
    400406 
     
    403409        PYERR_CLEAR(); 
    404410        PyGILState_Release(pystate); 
     411        osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error)); 
    405412        return FALSE; 
    406413} 
     
    493500static osync_bool scan_for_plugins(OSyncPluginEnv *env, PyObject *osync_module, OSyncError **error) 
    494501{ 
    495         osync_trace(TRACE_ENTRY, "%s(%p)", __func__, env); 
     502        osync_trace(TRACE_ENTRY, "%s(%p, %p)", __func__, env, osync_module); 
    496503 
    497504        GError *gerror = NULL; 
     
    581588osync_bool get_sync_info(OSyncPluginEnv *env, OSyncError **error) 
    582589{ 
    583         /* OpenSync likes to call this function multiple times. 
    584          * IMO this is a bug and should be fixed, however to work around it we have to: 
     590        osync_trace(TRACE_ENTRY, "%s(%p)", __func__, env); 
     591         
     592        /* Because OpenSync likes to call this function multiple times in 
     593         * different threads, and because we may be sharing the python 
     594         * interpreter with other code, we have to: 
    585595         *  * init python only once 
    586          *  * make sure we save and re-acquire the main thread before making any python API calls 
     596         *  * acquire the Python lock before making any API calls 
    587597         */ 
    588598 
    589599        if (!Py_IsInitialized()) { 
    590                 /* we're the first user of python in this process */ 
     600                /* We're the first user of python in this process. Initialise 
     601                 * it, enable threading, and release the lock that will be 
     602                 * re-acquired by the PyGILState_Ensure() call below. */ 
    591603                Py_InitializeEx(0); 
    592604                PyEval_InitThreads(); 
     605                PyEval_ReleaseLock(); 
    593606        } else if (!PyEval_ThreadsInitialized()) { 
    594                 /* The python interpreter has been initialised, but threads are not 
    595                  * I'm going to assume we're the only thread and continue, but this 
    596                 * is possibly unsafe! */ 
    597                 PyEval_InitThreads()
     607                /* Python has been initialised, but threads are not. */ 
     608                 osync_error_set(error, OSYNC_ERROR_GENERIC, "The Python interpreter in this process has been initialised without threading support."); 
     609                osync_trace(TRACE_EXIT_ERROR, "%s: %s", __func__, osync_error_print(error)); 
     610                return FALSE
    598611        } 
    599612 
     
    615628        PyGILState_Release(pystate); 
    616629 
     630        osync_trace(ret ? TRACE_EXIT : TRACE_EXIT_ERROR, "%s", __func__); 
    617631        return ret; 
    618632}