cq->context = context;\r
cq->channel = channel;\r
cq->cq_context = cq_context;\r
+ cq->notify_cnt = 0;\r
+ cq->ack_cnt = 0;\r
\r
entries = cqe;\r
hr = context->cmd_if->CreateCompletionQueue(&entries, &cq->handle);\r
HRESULT hr;\r
\r
if (InterlockedCompareExchange(&cq->comp_entry.Busy, 1, 0) == 0) {\r
+ InterlockedIncrement(&cq->notify_cnt);\r
hr = cq->handle->Notify(solicited_only ? WvCqSolicited : WvCqNextCompletion,\r
&cq->comp_entry.Overlap);\r
if (SUCCEEDED(hr) || hr == WV_IO_PENDING) {\r
hr = 0;\r
+ } else {\r
+ InterlockedExchange(&cq->comp_entry.Busy, 0);\r
+ InterlockedDecrement(&cq->notify_cnt);\r
}\r
} else {\r
hr = 0;\r
{\r
cq->handle->CancelOverlappedRequests();\r
if (cq->channel != NULL) {\r
- CompEntryCancel(&cq->comp_entry);\r
+ if (CompEntryCancel(&cq->comp_entry)) {\r
+ InterlockedIncrement(&cq->ack_cnt);\r
+ }\r
}\r
+\r
+ while (cq->ack_cnt < cq->notify_cnt)\r
+ Sleep(0);\r
cq->handle->Release();\r
delete cq;\r
return 0;\r
__declspec(dllexport)\r
void ibv_ack_cq_events(struct ibv_cq *cq, unsigned int nevents)\r
{\r
+ InterlockedExchangeAdd(&cq->ack_cnt, (LONG) nevents);\r
}\r
\r
__declspec(dllexport)\r