- if(req->isvoid && !force_sequence_wrap(c))
- {
- pthread_mutex_unlock(&c->iolock);
- return -1;
- }
-
- *request = ++c->out.request;
+ /* wait for other writing threads to get out of my way. */
+ while(c->out.writing)
+ pthread_cond_wait(&c->out.cond, &c->iolock);
+ get_socket_back(c);
+
+ /* send GetInputFocus (sync_req) when 64k-2 requests have been sent without
+ * a reply. */
+ if(req->isvoid && c->out.request == c->in.request_expected + (1 << 16) - 2)
+ send_sync(c);
+ /* Also send sync_req (could use NoOp) at 32-bit wrap to avoid having
+ * applications see sequence 0 as that is used to indicate
+ * an error in sending the request */
+ if((unsigned int) (c->out.request + 1) == 0)
+ send_sync(c);
+
+ /* The above send_sync calls could drop the I/O lock, but this
+ * thread will still exclude any other thread that tries to write,
+ * so the sequence number postconditions still hold. */
+ send_request(c, req->isvoid, workaround, flags, vector, veclen);
+ request = c->has_error ? 0 : c->out.request;
+ pthread_mutex_unlock(&c->iolock);
+ return request;
+}