@@ -244,14 +244,19 @@ class StreamResource { |
244 | 244 | // `*bufs` and `*count` accordingly. This is a no-op by default. |
245 | 245 | // Return 0 for success and a libuv error code for failures. |
246 | 246 | virtual int DoTryWrite(uv_buf_t** bufs, size_t* count); |
247 | | - // Initiate a write of data. If the write completes synchronously, return 0 on |
248 | | - // success (with bufs modified to indicate how much data was consumed) or a |
249 | | - // libuv error code on failure. If the write will complete asynchronously, |
250 | | - // return 0. When the write completes asynchronously, call req_wrap->Done() |
251 | | - // with 0 on success (with bufs modified to indicate how much data was |
252 | | - // consumed) or a libuv error code on failure. Do not call req_wrap->Done() if |
253 | | - // the write completes synchronously, that is, it should never be called |
254 | | - // before DoWrite() has returned. |
| 247 | + // Initiate a write of data. |
| 248 | + // Upon an immediate failure, a libuv error code is returned, |
| 249 | + // w->Done() will never be called and caller should free `bufs`. |
| 250 | + // Otherwise, 0 is returned and w->Done(status) will be called |
| 251 | + // with status set to either |
| 252 | + // (1) 0 after all data are written, or |
| 253 | + // (2) a libuv error code when an error occurs |
| 254 | + // in either case, w->Done() will never be called before DoWrite() returns. |
| 255 | + // When 0 is returned: |
| 256 | + // (1) memory specified by `bufs` and `count` must remain valid until |
| 257 | + // w->Done() gets called. |
| 258 | + // (2) `bufs` might or might not be changed, caller should not rely on this. |
| 259 | + // (3) `bufs` should be freed after w->Done() gets called. |
255 | 260 | virtual int DoWrite(WriteWrap* w, |
256 | 261 | uv_buf_t* bufs, |
257 | 262 | size_t count, |
@@ -343,13 +348,17 @@ class StreamBase : public StreamResource { |
343 | 348 | // WriteWrap object (that was created in JS), or a new one will be created. |
344 | 349 | // This will first try to write synchronously using `DoTryWrite()`, then |
345 | 350 | // asynchronously using `DoWrite()`. |
| 351 | + // Caller can pass `skip_try_write` as true if it has already called |
| 352 | + // `DoTryWrite()` and ends up with a partial write, or it knows that the |
| 353 | + // write is too large to finish synchronously. |
346 | 354 | // If the return value indicates a synchronous completion, no callback will |
347 | 355 | // be invoked. |
348 | 356 | inline StreamWriteResult Write( |
349 | 357 | uv_buf_t* bufs, |
350 | 358 | size_t count, |
351 | 359 | uv_stream_t* send_handle = nullptr, |
352 | | - v8::Local<v8::Object> req_wrap_obj = v8::Local<v8::Object>()); |
| 360 | + v8::Local<v8::Object> req_wrap_obj = v8::Local<v8::Object>(), |
| 361 | + bool skip_try_write = false); |
353 | 362 |
|
354 | 363 | // These can be overridden by subclasses to get more specific wrap instances. |
355 | 364 | // For example, a subclass Foo could create a FooWriteWrap or FooShutdownWrap |
|