More synchronizations for the Windows version. The problem came from
the multiple threads accessing the OOB/registry asynchronously via the callbacks. The quickest solution (but definitively not the cleanest) is to serialize these callbacks in such a way that at any given time only one thread can execute a callbacks. This commit was SVN r15086.
Этот коммит содержится в:
родитель
fb9ff5cc75
Коммит
a4d99ddef6
@ -58,6 +58,10 @@
|
||||
#include "orte/mca/ns/ns.h"
|
||||
#include "orte/mca/gpr/gpr.h"
|
||||
|
||||
#if defined(__WINDOWS__)
|
||||
static opal_mutex_t windows_callback;
|
||||
#endif /* defined(__WINDOWS__) */
|
||||
|
||||
/*
|
||||
* Data structure for accepting connections.
|
||||
*/
|
||||
@ -352,6 +356,11 @@ static int oob_tcp_windows_progress_callback( void )
|
||||
{
|
||||
opal_list_item_t* item;
|
||||
mca_oob_tcp_msg_t* msg;
|
||||
int event_count = 0;
|
||||
|
||||
/* Only one thread at the time is allowed to execute callbacks */
|
||||
if( !opal_mutex_trylock(&windows_callback) )
|
||||
return 0;
|
||||
|
||||
OPAL_THREAD_LOCK(&mca_oob_tcp_component.tcp_lock);
|
||||
while(NULL !=
|
||||
@ -364,12 +373,15 @@ static int oob_tcp_windows_progress_callback( void )
|
||||
msg->msg_ucnt,
|
||||
msg->msg_hdr.msg_tag,
|
||||
msg->msg_cbdata);
|
||||
event_count++;
|
||||
OPAL_THREAD_LOCK(&mca_oob_tcp_component.tcp_lock);
|
||||
MCA_OOB_TCP_MSG_RETURN(msg);
|
||||
}
|
||||
OPAL_THREAD_UNLOCK(&mca_oob_tcp_component.tcp_lock);
|
||||
|
||||
return 0;
|
||||
opal_mutex_unlock(&windows_callback);
|
||||
|
||||
return event_count;
|
||||
}
|
||||
#endif /* defined(__WINDOWS__) */
|
||||
|
||||
@ -381,6 +393,7 @@ int mca_oob_tcp_component_close(void)
|
||||
{
|
||||
#if defined(__WINDOWS__)
|
||||
opal_progress_unregister(oob_tcp_windows_progress_callback);
|
||||
OBJ_DESTRUCT( &windows_callback );
|
||||
WSACleanup();
|
||||
#endif /* defined(__WINDOWS__) */
|
||||
|
||||
@ -1040,6 +1053,7 @@ mca_oob_t* mca_oob_tcp_component_init(int* priority)
|
||||
#if defined(__WINDOWS__)
|
||||
/* Register the libevent callback which will trigger the OOB
|
||||
* completion callbacks. */
|
||||
OBJ_CONSTRUCT(&windows_callback, opal_mutex_t);
|
||||
opal_progress_register(oob_tcp_windows_progress_callback);
|
||||
#endif /* defined(__WINDOWS__) */
|
||||
|
||||
|
@ -188,13 +188,13 @@ int mca_oob_tcp_msg_complete(mca_oob_tcp_msg_t* msg, orte_process_name_t * peer)
|
||||
opal_list_append(&mca_oob_tcp_component.tcp_msg_completed, (opal_list_item_t*)msg);
|
||||
#if defined(__WINDOWS__)
|
||||
/**
|
||||
* In order to be able to generate TCP events reccursively, Windows need
|
||||
* In order to be able to generate TCP events recursively, Windows need
|
||||
* to get out of the callback attached to a specific socket. Therefore,
|
||||
* as our OOB allow to block on a connection from a callback on the same
|
||||
* connection, we have to trigger the completion callbacks outside of the
|
||||
* OOB callbacks. We add them to the completed list here, and the progress
|
||||
* engine will call our progress function later once all socket related
|
||||
* callbacks have been triggered.
|
||||
* events have been processed.
|
||||
*/
|
||||
OPAL_THREAD_UNLOCK(&mca_oob_tcp_component.tcp_lock);
|
||||
return ORTE_SUCCESS;
|
||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user