@@ -147,19 +147,30 @@ bool Transporter::IsServerMode() const {
147147typedef struct {
148148 uv_write_t req;
149149 uv_buf_t buf;
150+ uv_stream_t * handler;
150151} write_req_t ;
151152
152153static void after_write (uv_write_t * req, int status) {
153- const auto writeReq = reinterpret_cast <write_req_t *>(req);
154+ const auto * writeReq = reinterpret_cast <write_req_t *>(req);
154155 free (writeReq->buf .base );
155156 delete writeReq;
156157}
157158
159+ static void after_async (uv_handle_t * h) {
160+ delete h;
161+ }
162+
163+ static void async_write (uv_async_t * h) {
164+ auto * writeReq = (write_req_t *)h->data ;
165+ uv_write (&writeReq->req , writeReq->handler , &writeReq->buf , 1 , after_write);
166+ uv_close ((uv_handle_t *)h, after_async);
167+ }
168+
158169void Transporter::Send (uv_stream_t * handler, int cmd, const char * data, size_t len) {
159170 if (!IsConnected ()) {
160171 return ;
161172 }
162- auto writeReq = new write_req_t ();
173+ auto * writeReq = new write_req_t ();
163174 char cmdValue[100 ];
164175 const int l1 = sprintf (cmdValue, " %d\n " , cmd);
165176 const size_t newLen = len + l1 + 1 ;
@@ -170,7 +181,13 @@ void Transporter::Send(uv_stream_t* handler, int cmd, const char* data, size_t l
170181 memcpy (newData + l1, data, len);
171182 newData[newLen - 1 ] = ' \n ' ;
172183 writeReq->buf = uv_buf_init (newData, newLen);
173- uv_write (&writeReq->req , handler, &writeReq->buf , 1 , after_write);
184+ writeReq->handler = handler;
185+
186+ // thread safe:
187+ auto * async = new uv_async_t ;
188+ async->data = writeReq;
189+ uv_async_init (loop, async, async_write);
190+ uv_async_send (async);
174191}
175192
176193void Transporter::StartEventLoop () {
0 commit comments