\r
\r
/* Signals a select event to the switch. */\r
-static void\r
-post_select_event(\r
+void\r
+ibsp_post_select_event(\r
struct ibsp_socket_info *socket_info,\r
int event,\r
int error )\r
{\r
- CL_ENTER( IBSP_DBG_NEV, gdbg_lvl );\r
+ HANDLE h_event;\r
\r
- if( (socket_info->event_mask & event) == 0 )\r
- {\r
- /* This event is not requested. Since we capture only two important\r
- * event, this case should never occur. */\r
- CL_EXIT_ERROR( IBSP_DBG_NEV, gdbg_lvl,\r
- ("Hummm, tried to post an umasked event. (%x, %x)\n",\r
- socket_info->event_mask, event) );\r
- return;\r
- }\r
+ IBSP_ENTER( IBSP_DBG_NEV );\r
\r
- cl_spinlock_acquire( &socket_info->event_mutex );\r
-\r
- socket_info->network_events |= event;\r
+ CL_ASSERT( socket_info );\r
+ CL_ASSERT( event );\r
\r
switch( event )\r
{\r
case FD_CONNECT:\r
+ IBSP_TRACE1( IBSP_DBG_NEV,\r
+ ("socket %p FD_CONNECT\n", socket_info) );\r
socket_info->errno_connect = error;\r
break;\r
\r
case FD_ACCEPT:\r
- socket_info->errno_accept = error;\r
+ IBSP_TRACE1( IBSP_DBG_NEV,\r
+ ("socket %p FD_ACCEPT\n", socket_info) );\r
break;\r
\r
default:\r
break;\r
}\r
\r
- cl_spinlock_release( &socket_info->event_mutex );\r
+ _InterlockedOr( &socket_info->network_events, event );\r
\r
- SetEvent( socket_info->event_select );\r
+ h_event = InterlockedCompareExchangePointer(\r
+ &socket_info->event_select, NULL, NULL );\r
+ /* Check for event notification request and signal as needed. */\r
+ if( (socket_info->event_mask & event) && h_event )\r
+ {\r
+ IBSP_TRACE2( IBSP_DBG_NEV,\r
+ ("Signaling eventHandle %p at time %I64d.\n",\r
+ h_event, cl_get_time_stamp() ) );\r
+ SetEvent( h_event );\r
+ }\r
\r
- CL_EXIT( IBSP_DBG_NEV, gdbg_lvl );\r
+ IBSP_EXIT( IBSP_DBG_NEV );\r
}\r
\r
\r
mra.svc_timeout = 0x1F;\r
ib_cm_mra( p_cm_req_rec->h_cm_req, &mra );\r
\r
- post_select_event( socket_info, FD_ACCEPT, 0 );\r
+ ibsp_post_select_event( socket_info, FD_ACCEPT, 0 );\r
break;\r
\r
case IBSP_DUPLICATING_REMOTE:\r
/* Note: a REJ has been automatically sent. */\r
CL_ERROR( IBSP_DBG_CM, gdbg_lvl, ("ib_cm_rtu failed (0x%d)\n", status) );\r
IBSP_CHANGE_SOCKET_STATE( socket_info, IBSP_BIND );\r
- post_select_event( socket_info, FD_CONNECT, WSAENOBUFS );\r
+ ibsp_post_select_event( socket_info, FD_CONNECT, WSAENOBUFS );\r
}\r
else\r
{\r
IBSP_CHANGE_SOCKET_STATE( socket_info, IBSP_CONNECTED );\r
- post_select_event( socket_info, FD_CONNECT, 0 );\r
+ ibsp_post_select_event( socket_info, FD_CONNECT, 0 );\r
}\r
}\r
else if( socket_info->socket_state == IBSP_DUPLICATING_NEW )\r
{\r
case IBSP_CONNECT:\r
IBSP_CHANGE_SOCKET_STATE( socket_info, IBSP_BIND );\r
- post_select_event( socket_info, FD_CONNECT, WSAECONNREFUSED );\r
+ ibsp_post_select_event( socket_info, FD_CONNECT, WSAECONNREFUSED );\r
break;\r
\r
case IBSP_ACCEPT:\r
WSABUF callee_id;\r
struct listen_incoming *incoming;\r
struct ibsp_port *port;\r
- BOOLEAN reject;\r
\r
- CL_ENTER( IBSP_DBG_CONN, gdbg_lvl );\r
+ IBSP_ENTER( IBSP_DBG_CONN );\r
\r
fzprint(("%s():%d:0x%x:0x%x: socket=0x%p \n", __FUNCTION__,\r
__LINE__, GetCurrentProcessId(), GetCurrentThreadId(), s));\r
\r
if( *addrlen < sizeof(struct sockaddr_in) )\r
{\r
- CL_EXIT_ERROR( IBSP_DBG_CONN, gdbg_lvl,\r
- ("invalid addrlen (%d, %d)\n", *addrlen, sizeof(struct sockaddr_in)) );\r
+ IBSP_ERROR_EXIT( ("invalid addrlen (%d, %d)\n",\r
+ *addrlen, sizeof(struct sockaddr_in)) );\r
*lpErrno = WSAEFAULT;\r
return INVALID_SOCKET;\r
}\r
if( socket_info->socket_state != IBSP_LISTEN )\r
{\r
cl_spinlock_release( &socket_info->mutex );\r
- CL_EXIT_ERROR( IBSP_DBG_CONN, gdbg_lvl,\r
- ("Socket is not in right socket_state (%s)\n",\r
+ IBSP_ERROR_EXIT( ("Socket is not in right socket_state (%s)\n",\r
IBSP_SOCKET_STATE_STR( socket_info->socket_state )) );\r
*lpErrno = WSAEINVAL;\r
return INVALID_SOCKET;\r
{\r
cl_spinlock_release( &socket_info->mutex );\r
\r
- CL_EXIT_ERROR( IBSP_DBG_CONN, gdbg_lvl,\r
- ("No pending connection found for this socket\n") );\r
+ IBSP_ERROR_EXIT( ("No pending connection found for this socket\n") );\r
*lpErrno = WSAEWOULDBLOCK;\r
return INVALID_SOCKET;\r
}\r
struct listen_incoming, item);\r
port = socket_info->port;\r
\r
- reject = FALSE;\r
-\r
/* Find the destination IP address */\r
if( port == NULL )\r
{\r
/* The socket was bound to INADDR_ANY. We must find the correct port\r
- * for the new socket. */\r
+ * for the new socket. */\r
port = get_port_from_ip_address( incoming->params.dest.sin_addr );\r
if( port == NULL )\r
{\r
- CL_ERROR( IBSP_DBG_CONN, gdbg_lvl,\r
+ IBSP_ERROR(\r
("incoming destination IP address not local (%s)\n",\r
inet_ntoa( incoming->params.dest.sin_addr )) );\r
goto reject;\r
/* Cross-check with the path info to make sure we are conectiong correctly */\r
if( port->guid != ib_gid_get_guid( &incoming->cm_req_received.primary_path.sgid ) )\r
{\r
- CL_ERROR( IBSP_DBG_CONN, gdbg_lvl,\r
+ IBSP_ERROR(\r
("GUIDs of port for destination IP address and primary path do not match (%016I64x, %016I64x)\n",\r
port->guid,\r
ib_gid_get_guid( &incoming->cm_req_received.primary_path.sgid )) );\r
- goto reject;\r
- }\r
\r
- if( reject )\r
- {\r
reject:\r
/* The request is invalid. Remove it from the list and reject it. */\r
cl_qlist_remove_item( &socket_info->info.listen.list, &incoming->item );\r
callee_id.buf = (char *)&incoming->params.dest;\r
callee_id.len = sizeof(incoming->params.dest);\r
\r
-#ifdef _DEBUG_\r
- {\r
- char buf[100];\r
- char *p = buf;\r
- p += sprintf( p, "got incoming connection from %s/%d-%d to",\r
- inet_ntoa( incoming->params.source.sin_addr ),\r
- cl_ntoh16( incoming->params.source.sin_port ),\r
- incoming->params.source.sin_family );\r
- p += sprintf( p, " %s/%d-%d",\r
- inet_ntoa( incoming->params.dest.sin_addr ),\r
- cl_ntoh16( incoming->params.dest.sin_port ),\r
- incoming->params.dest.sin_family );\r
-\r
- CL_TRACE( IBSP_DBG_CONN, gdbg_lvl, (buf) );\r
- }\r
-#endif\r
+ IBSP_TRACE( IBSP_DBG_CONN,\r
+ ("Got incoming conn from %s/%d-%d to %s/%d-%d\n",\r
+ inet_ntoa( incoming->params.source.sin_addr ),\r
+ cl_ntoh16( incoming->params.source.sin_port ),\r
+ incoming->params.source.sin_family,\r
+ inet_ntoa( incoming->params.dest.sin_addr ),\r
+ cl_ntoh16( incoming->params.dest.sin_port ),\r
+ incoming->params.dest.sin_family) );\r
\r
/* Call the conditional function */\r
- ret = lpfnCondition( &caller_id, NULL,\r
- NULL, NULL, &callee_id, NULL, NULL, dwCallbackData );\r
+ ret = lpfnCondition( &caller_id, NULL, NULL, NULL,\r
+ &callee_id, NULL, NULL, dwCallbackData );\r
\r
switch( ret )\r
{\r
cl_qlist_remove_item( &socket_info->info.listen.list, &incoming->item );\r
cl_spinlock_release( &socket_info->mutex );\r
\r
- ib_reject( incoming->cm_req_received.h_cm_req, IB_REJ_INSUF_QP );\r
+ IBSP_TRACE1( IBSP_DBG_CONN,\r
+ ("Conditional routine returned CF_REJECT\n") );\r
+\r
+ ib_reject( incoming->cm_req_received.h_cm_req, IB_REJ_USER_DEFINED );\r
\r
HeapFree( g_ibsp.heap, 0, incoming );\r
- CL_EXIT_ERROR( IBSP_DBG_CONN, gdbg_lvl,\r
- ("Conditional routine rejected connection\n") );\r
*lpErrno = WSAECONNREFUSED;\r
+ IBSP_EXIT( IBSP_DBG_CONN );\r
return INVALID_SOCKET;\r
- break;\r
\r
case CF_DEFER:\r
cl_spinlock_release( &socket_info->mutex );\r
\r
- CL_EXIT_ERROR( IBSP_DBG_CONN, gdbg_lvl, ("Conditional routine returned defer\n") );\r
+ IBSP_TRACE1( IBSP_DBG_CONN,\r
+ ("Conditional routine returned CF_DEFER\n") );\r
/* TODO: Send MRA */\r
*lpErrno = WSATRY_AGAIN;\r
+ IBSP_EXIT( IBSP_DBG_CONN );\r
return INVALID_SOCKET;\r
- break;\r
\r
case CF_ACCEPT:\r
break;\r
default:\r
/* Should never happen */\r
cl_spinlock_release( &socket_info->mutex );\r
- CL_ERROR( IBSP_DBG_CONN, gdbg_lvl,\r
- ("lpfnCondition returned undocumented code (%d)\n", ret) );\r
+ IBSP_ERROR(\r
+ ("Conditional routine returned undocumented code (%d)\n", ret) );\r
CL_ASSERT( 0 );\r
*lpErrno = WSAECONNREFUSED;\r
+ IBSP_EXIT( IBSP_DBG_CONN );\r
return INVALID_SOCKET;\r
}\r
\r
new_socket_info->local_addr = incoming->params.dest;\r
\r
cl_qlist_remove_item( &socket_info->info.listen.list, &incoming->item );\r
+ /* Signal the event again if there are more connection requests. */\r
+ if( cl_qlist_count( &socket_info->info.listen.list ) )\r
+ ibsp_post_select_event( socket_info, FD_ACCEPT, 0 );\r
\r
cl_spinlock_release( &socket_info->mutex );\r
\r
- /* Update the state of the socket context */\r
- IBSP_CHANGE_SOCKET_STATE( new_socket_info, IBSP_ACCEPT );\r
-\r
/* Copy the socket context info from parent socket context */\r
new_socket_info->socket_options = socket_info->socket_options;\r
\r
\r
new_socket_info->info.accept.event = CreateEvent( NULL, FALSE, FALSE, NULL );\r
\r
+ cl_spinlock_acquire( &new_socket_info->mutex );\r
+ /* Update the state of the socket context */\r
+ IBSP_CHANGE_SOCKET_STATE( new_socket_info, IBSP_ACCEPT );\r
+\r
ret = ib_accept( new_socket_info, &incoming->cm_req_received, lpErrno );\r
\r
if( ret )\r
{\r
+ IBSP_CHANGE_SOCKET_STATE( new_socket_info, IBSP_CREATE );\r
+ cl_spinlock_release( &new_socket_info->mutex );\r
/* Free the socket descriptor */\r
fzprint(("%s():%d:0x%x:0x%x: socket=0x%p calling lpWPUCloseSocketHandle=0x%p\n",\r
__FUNCTION__, __LINE__, GetCurrentProcessId(), GetCurrentThreadId(),\r
socket_info, socket_info->switch_socket));\r
\r
if( g_ibsp.up_call_table.lpWPUCloseSocketHandle(\r
- new_socket_info->switch_socket, lpErrno ) == SOCKET_ERROR )\r
+ new_socket_info->switch_socket, &ret ) == SOCKET_ERROR )\r
{\r
- CL_ERROR( IBSP_DBG_CONN, gdbg_lvl,\r
- ("WPUCloseSocketHandle failed: %d\n", *lpErrno) );\r
+ IBSP_ERROR( ("WPUCloseSocketHandle failed: %d\n", ret) );\r
}\r
else\r
{\r
ib_reject( incoming->cm_req_received.h_cm_req, IB_REJ_INSUF_QP );\r
\r
HeapFree( g_ibsp.heap, 0, incoming );\r
- *lpErrno = WSAEACCES;\r
+ *lpErrno = ret;\r
\r
CL_EXIT_ERROR( IBSP_DBG_CONN, gdbg_lvl, ("ib_accept failed (%d)\n", ret) );\r
\r
}\r
else\r
{\r
+ cl_spinlock_release( &new_socket_info->mutex );\r
HeapFree( g_ibsp.heap, 0, incoming );\r
\r
if( WaitForSingleObject( new_socket_info->info.accept.event, INFINITE ) == WAIT_OBJECT_0 )\r
}\r
else\r
{\r
- CL_ERROR( IBSP_DBG_CONN, gdbg_lvl,\r
+ IBSP_ERROR(\r
("ib_accept failed - socket state is %s\n",\r
IBSP_SOCKET_STATE_STR( new_socket_info->socket_state )) );\r
\r
if( g_ibsp.up_call_table.lpWPUCloseSocketHandle(\r
new_socket_info->switch_socket, lpErrno ) == SOCKET_ERROR )\r
{\r
- CL_ERROR( IBSP_DBG_CONN, gdbg_lvl,\r
+ IBSP_ERROR(\r
("WPUCloseSocketHandle failed: %d\n", *lpErrno) );\r
}\r
else\r
("returns new SocketID (0x%x)\n", new_socket) );\r
\r
return (SOCKET) new_socket_info;\r
-\r
}\r
else\r
{\r
/* Sanity checks */\r
if( namelen != sizeof(struct sockaddr_in) )\r
{\r
- CL_ERROR( IBSP_DBG_CONN, gdbg_lvl,\r
+ IBSP_ERROR(\r
("invalid namelen (%d instead of %d)\n",\r
namelen, sizeof(struct sockaddr_in)) );\r
*lpErrno = WSAEFAULT;\r
\r
if( addr->sin_family != AF_INET )\r
{\r
- CL_ERROR( IBSP_DBG_CONN, gdbg_lvl, ("bad family for socket\n") );\r
+ IBSP_ERROR( ("bad family for socket\n") );\r
*lpErrno = WSAEFAULT;\r
goto error;\r
}\r
port = get_port_from_ip_address( addr->sin_addr );\r
if( port == NULL )\r
{\r
- CL_ERROR( IBSP_DBG_CONN, gdbg_lvl,\r
+ IBSP_ERROR(\r
("This IP address does not belong to that host (%08x)\n",\r
addr->sin_addr.S_un.S_addr) );\r
*lpErrno = WSAEADDRNOTAVAIL;\r
\r
/* We are going to take this mutex for some time, \r
* but at this stage, it shouldn't impact anything. */\r
- cl_spinlock_acquire( &socket_info->event_mutex );\r
+ cl_spinlock_acquire( &socket_info->mutex );\r
\r
/* Verify the state of the socket */\r
if( socket_info->socket_state != IBSP_CREATE )\r
{\r
- cl_spinlock_release( &socket_info->event_mutex );\r
- CL_ERROR( IBSP_DBG_CONN, gdbg_lvl,\r
+ cl_spinlock_release( &socket_info->mutex );\r
+ IBSP_ERROR(\r
("Invalid socket state (%s)\n",\r
IBSP_SOCKET_STATE_STR( socket_info->socket_state )) );\r
*lpErrno = WSAEINVAL;\r
if( ret )\r
{\r
socket_info->port = NULL;\r
- cl_spinlock_release( &socket_info->event_mutex );\r
- CL_ERROR( IBSP_DBG_CONN, gdbg_lvl, ("ib_create socket failed with %d\n", ret) );\r
+ cl_spinlock_release( &socket_info->mutex );\r
+ IBSP_ERROR( ("ib_create socket failed with %d\n", ret) );\r
*lpErrno = WSAENOBUFS;\r
goto error;\r
}\r
\r
IBSP_CHANGE_SOCKET_STATE( socket_info, IBSP_BIND );\r
\r
- cl_spinlock_release( &socket_info->event_mutex );\r
+ cl_spinlock_release( &socket_info->mutex );\r
\r
CL_EXIT( IBSP_DBG_CONN, gdbg_lvl );\r
return 0;\r
cl_atomic_inc( &g_ibsp.CloseSocket_count );\r
#endif\r
\r
- cl_spinlock_acquire( &socket_info->event_mutex );\r
-\r
+ cl_spinlock_acquire( &socket_info->mutex );\r
\r
old_state = socket_info->socket_state;\r
IBSP_CHANGE_SOCKET_STATE( socket_info, IBSP_CLOSING );\r
\r
- cl_spinlock_release( &socket_info->event_mutex );\r
+ cl_spinlock_release( &socket_info->mutex );\r
\r
shutdown_and_destroy_socket_info( socket_info, old_state );\r
\r
- cl_spinlock_acquire( &socket_info->event_mutex );\r
+ cl_spinlock_acquire( &socket_info->mutex );\r
IBSP_CHANGE_SOCKET_STATE( socket_info, IBSP_CLOSED );\r
- cl_spinlock_release( &socket_info->event_mutex );\r
+ cl_spinlock_release( &socket_info->mutex );\r
\r
/* Take off socket_info_list and put on closed_socket_info_list */\r
cl_spinlock_acquire( &g_ibsp.socket_info_mutex );\r
/* Notify ib_cleanup_thread() to free this */\r
SetEvent( g_ibsp.ib_cleanup_event );\r
\r
-\r
CL_EXIT( IBSP_DBG_CONN, gdbg_lvl );\r
\r
*lpErrno = 0;\r
LPWSANETWORKEVENTS lpNetworkEvents,\r
LPINT lpErrno )\r
{\r
- struct ibsp_socket_info *socket_info = (struct ibsp_socket_info *)s;\r
-\r
- CL_ENTER( IBSP_DBG_NEV, gdbg_lvl );\r
+ struct ibsp_socket_info *socket_info = (struct ibsp_socket_info *)s;\r
\r
- fzprint(("%s():%d:0x%x:0x%x: socket=0x%p \n", __FUNCTION__,\r
- __LINE__, GetCurrentProcessId(), GetCurrentThreadId(), s));\r
+ IBSP_ENTER( IBSP_DBG_NEV );\r
\r
- cl_spinlock_acquire( &socket_info->event_mutex );\r
+ ResetEvent( hEventObject );\r
\r
- lpNetworkEvents->lNetworkEvents = 0;\r
+ lpNetworkEvents->lNetworkEvents =\r
+ InterlockedExchange( &socket_info->network_events, 0 );\r
\r
- if( socket_info->network_events & FD_ACCEPT )\r
+ if( lpNetworkEvents->lNetworkEvents & FD_ACCEPT )\r
{\r
- CL_TRACE( IBSP_DBG_NEV, gdbg_lvl, ("FD_ACCEPT\n") );\r
- lpNetworkEvents->lNetworkEvents |= FD_ACCEPT;\r
- lpNetworkEvents->iErrorCode[FD_ACCEPT_BIT] = socket_info->errno_accept;\r
+ IBSP_TRACE1( IBSP_DBG_NEV,\r
+ ("socket %p notify FD_ACCEPT at time %I64d\n",\r
+ socket_info, cl_get_time_stamp()) );\r
+ lpNetworkEvents->iErrorCode[FD_ACCEPT_BIT] = 0;\r
}\r
\r
- if( socket_info->network_events & FD_CONNECT )\r
+ if( lpNetworkEvents->lNetworkEvents & FD_CONNECT )\r
{\r
- CL_TRACE( IBSP_DBG_NEV, gdbg_lvl, ("FD_CONNECT\n") );\r
- lpNetworkEvents->lNetworkEvents |= FD_CONNECT;\r
+ IBSP_TRACE1( IBSP_DBG_NEV,\r
+ ("socket %p notify FD_CONNECT %d at time %I64d\n",\r
+ socket_info, socket_info->errno_connect, cl_get_time_stamp()) );\r
lpNetworkEvents->iErrorCode[FD_CONNECT_BIT] = socket_info->errno_connect;\r
}\r
\r
- socket_info->network_events = 0;\r
-\r
- ResetEvent( hEventObject );\r
-\r
- cl_spinlock_release( &socket_info->event_mutex );\r
-\r
- CL_TRACE_EXIT( IBSP_DBG_NEV, gdbg_lvl,\r
- ("returning %x, accept=%d, connect=%d\n",\r
- lpNetworkEvents->lNetworkEvents,\r
- lpNetworkEvents->iErrorCode[FD_ACCEPT_BIT],\r
- lpNetworkEvents->iErrorCode[FD_CONNECT_BIT]) );\r
-\r
*lpErrno = 0;\r
+ IBSP_EXIT( IBSP_DBG_NEV );\r
return 0;\r
}\r
\r
long lNetworkEvents,\r
LPINT lpErrno )\r
{\r
- struct ibsp_socket_info *socket_info = (struct ibsp_socket_info *)s;\r
+ struct ibsp_socket_info *socket_info = (struct ibsp_socket_info *)s;\r
+ long events;\r
\r
- CL_ENTER( IBSP_DBG_NEV, gdbg_lvl );\r
+ IBSP_ENTER( IBSP_DBG_NEV );\r
\r
- fzprint(("%s():%d:0x%x:0x%x: socket=0x%p\n", __FUNCTION__,\r
- __LINE__, GetCurrentProcessId(), GetCurrentThreadId(), s));\r
+ IBSP_TRACE4( IBSP_DBG_NEV,\r
+ ("Socket %p requesting notifiction of %d on event %p.\n",\r
+ s, lNetworkEvents, hEventObject) );\r
\r
if( (lNetworkEvents & ~(FD_ACCEPT | FD_CONNECT)) != 0 )\r
{\r
- CL_TRACE_EXIT(IBSP_DBG_NEV, gdbg_lvl,\r
+ IBSP_TRACE_EXIT(IBSP_DBG_NEV,\r
("Unknown lNetworkEvents flag given (%x)\n", lNetworkEvents) );\r
*lpErrno = WSAEINVAL;\r
return SOCKET_ERROR;\r
}\r
\r
- CL_ASSERT( (hEventObject == NULL && socket_info->event_select != NULL) ||\r
- (hEventObject != NULL && socket_info->event_select == NULL) );\r
CL_ASSERT( lpErrno );\r
\r
- if( hEventObject )\r
- socket_info->event_select = hEventObject;\r
socket_info->event_mask = lNetworkEvents;\r
+ InterlockedExchangePointer( &socket_info->event_select, hEventObject );\r
+\r
+ events = InterlockedCompareExchange( &socket_info->network_events, 0, 0 );\r
+ /* Check for existing events and signal as appropriate. */\r
+ if( (socket_info->event_mask & events) && hEventObject )\r
+ {\r
+ IBSP_TRACE2( IBSP_DBG_NEV,\r
+ ("Signaling eventHandle %p .\n", socket_info->event_select) );\r
+ SetEvent( hEventObject );\r
+ }\r
\r
- CL_EXIT( IBSP_DBG_NEV, gdbg_lvl );\r
+ IBSP_EXIT( IBSP_DBG_NEV );\r
return 0;\r
}\r
\r