umad_recv is a blocking call. Provide a routine that will unblock any thread waiting in umad_recv.
Signed-off-by: Sean Hefty <[email protected]> --- umad_cancel_recv is a Windows specific call, but it could easily be implemented on Linux. There really isn't a good way to handle this that doesn't end up being OS specific. I tested the compile and that the existing diags still ran okay, but did not test this actual call. You should be able to call this from opensm umad_receiver_stop before trying to destroy the thread. I don't know if opensm requires other changes or how umad_receiver_stop gets invoked. trunk/ulp/libibumad/include/infiniband/umad.h | 2 ++ trunk/ulp/libibumad/src/ibum_exports.src | 1 + trunk/ulp/libibumad/src/umad.cpp | 17 ++++++++++------- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/trunk/ulp/libibumad/include/infiniband/umad.h b/trunk/ulp/libibumad/include/infiniband/umad.h index aceebf3..8da5996 100644 --- a/trunk/ulp/libibumad/include/infiniband/umad.h +++ b/trunk/ulp/libibumad/include/infiniband/umad.h @@ -189,6 +189,8 @@ int umad_recv(int portid, void *umad, int *length, int timeout_ms); __declspec(dllexport) int umad_poll(int portid, int timeout_ms); HANDLE umad_get_fd(int portid); +__declspec(dllexport) +int umad_cancel_recv(int portid); __declspec(dllexport) int umad_register(int portid, int mgmt_class, int mgmt_version, diff --git a/trunk/ulp/libibumad/src/ibum_exports.src b/trunk/ulp/libibumad/src/ibum_exports.src index d79244e..b32a837 100644 --- a/trunk/ulp/libibumad/src/ibum_exports.src +++ b/trunk/ulp/libibumad/src/ibum_exports.src @@ -36,4 +36,5 @@ EXPORTS umad_debug; umad_addr_dump; umad_dump; + umad_cancel_recv; #endif diff --git a/trunk/ulp/libibumad/src/umad.cpp b/trunk/ulp/libibumad/src/umad.cpp index 19582dc..47a6766 100644 --- a/trunk/ulp/libibumad/src/umad.cpp +++ b/trunk/ulp/libibumad/src/umad.cpp @@ -599,12 +599,11 @@ int umad_send(int portid, int agentid, void *umad, int length, return 0; } -static HRESULT umad_cancel_recv(um_port_t *port) +__declspec(dllexport) +int umad_cancel_recv(int portid) { - DWORD bytes; - - port->prov->CancelOverlappedRequests(); - return port->prov->GetOverlappedResult(&port->overlap, &bytes, TRUE); + ports[portid].prov->CancelOverlappedRequests(); + return 0; } __declspec(dllexport) @@ -613,6 +612,7 @@ int umad_recv(int portid, void *umad, int *length, int timeout_ms) WM_MAD *mad = (WM_MAD *) umad; um_port_t *port; HRESULT hr; + DWORD bytes; port = &ports[portid]; ResetEvent(port->overlap.hEvent); @@ -620,7 +620,8 @@ int umad_recv(int portid, void *umad, int *length, int timeout_ms) if (hr == WV_IO_PENDING) { hr = WaitForSingleObject(port->overlap.hEvent, (DWORD) timeout_ms); if (hr == WAIT_TIMEOUT) { - hr = umad_cancel_recv(port); + port->prov->CancelOverlappedRequests(); + hr = port->prov->GetOverlappedResult(&port->overlap, &bytes, TRUE); if (hr == WV_CANCELLED) { _set_errno(EWOULDBLOCK); return -EWOULDBLOCK; @@ -651,6 +652,7 @@ int umad_poll(int portid, int timeout_ms) WM_MAD mad; um_port_t *port; HRESULT hr; + DWORD bytes; port = &ports[portid]; ResetEvent(port->overlap.hEvent); @@ -658,7 +660,8 @@ int umad_poll(int portid, int timeout_ms) if (hr == WV_IO_PENDING) { hr = WaitForSingleObject(port->overlap.hEvent, (DWORD) timeout_ms); if (hr == WAIT_TIMEOUT) { - hr = umad_cancel_recv(port); + port->prov->CancelOverlappedRequests(); + hr = port->prov->GetOverlappedResult(&port->overlap, &bytes, TRUE); if (hr == WV_CANCELLED) { _set_errno(ETIMEDOUT); return -ETIMEDOUT; _______________________________________________ ofw mailing list [email protected] http://lists.openfabrics.org/cgi-bin/mailman/listinfo/ofw
