void slp_end_call(slp_handle_impl_t *hp) { (void) mutex_lock(&(hp->outcall_lock)); if (hp->close_on_end) { /* SLPClose() called from callback */ (void) mutex_unlock(&(hp->outcall_lock)); slp_cleanup_handle(hp); return; } hp->pending_outcall = SLP_FALSE; (void) cond_signal(&(hp->outcall_cv)); (void) mutex_unlock(&(hp->outcall_lock)); }
void SLPClose(SLPHandle hSLP) { slp_handle_impl_t *hp = (slp_handle_impl_t *)hSLP; if (!hSLP) { return; } /* * If an outcall is pending on this handle: * If we are being called from a callback resulting * from the outcall associated with this handle or * if close_on_end has already been set: * just set close on end and return -- the cleanup * will be done when the outcall is finished. * else * wait on the outcall cv for the outcall to complete * Proceed with cleanup */ (void) mutex_lock(&(hp->outcall_lock)); if (hp->pending_outcall) { /* end the consumer thread */ /* this will also kill the producer thread and close net */ hp->cancel = 1; if (hp->q) { if (slp_enqueue_at_head(hp->q, NULL) != SLP_OK) { goto cleanup; } } if (thr_self() == hp->consumer_tid || hp->close_on_end) { /* SLPClose called from callback */ hp->close_on_end = SLP_TRUE; (void) mutex_unlock(&(hp->outcall_lock)); return; } /* else not called from callback; wait for outcall to end */ while (hp->pending_outcall) { (void) cond_wait(&(hp->outcall_cv), &(hp->outcall_lock)); } } (void) mutex_unlock(&(hp->outcall_lock)); cleanup: slp_cleanup_handle(hp); }