12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667openCoreopenAsyncmoduleUnix=Core.Unixletserializet~yield~writev=letshutdown()=Faraday.closet;(* It's necessary to drain the serializer in order to free any buffers that
* be queued up. *)ignore(Faraday.draint)inletrecloopt=matchFaraday.operationtwith|`Writeviovecs->writeviovecs>>=(function|`Closed->shutdown();return()(* XXX(seliopou): this should be reported *)|`Okn->Faraday.shifttn;loopt)|`Yield->yieldt>>=fun()->loopt|`Close->return()intry_with~extract_exn:true(fun()->loopt)>>|function|Result.Ok()->()|Result.Errorexn->shutdown();raiseexnletwritev_of_fdfd=letbadfd=failwithf"writev_of_fd got bad fd: %s"(Fd.to_stringfd)inletfinishresult=letopenUnix.Errorinmatchresultwith|`Okn->return(`Okn)|`Already_closed->return`Closed|`Error(Unix.Unix_error((EWOULDBLOCK|EAGAIN),_,_))->beginFd.ready_tofd`Write>>|function|`Bad_fd->badfd()|`Closed->`Closed|`Ready->`Ok0end|`Error(Unix.Unix_error(EBADF,_,_))->badfd()|`Errorexn->Deferred.don't_wait_for(Fd.closefd);raiseexninfuniovecs->letiovecs=Array.of_list_mapiovecs~f:(funiovec->let{Faraday.buffer;off=pos;len}=iovecinUnix.IOVec.of_bigstring~pos~lenbuffer)inifFd.supports_nonblockfdthenfinish(Fd.syscallfd~nonblocking:true(funfile_descr->Bigstring.writev_assume_fd_is_nonblockingfile_descriovecs))elseFd.syscall_in_threadfd~name:"writev"(funfile_descr->Bigstring.writevfile_descriovecs)>>=finish