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

Reply via email to