1 #include "hphp/runtime/base/file-await.h"
2 #include "hphp/runtime/base/file.h"
3 #include "hphp/runtime/ext/asio/ext_static-wait-handle.h"
5 #include "hphp/util/compatibility.h"
8 /////////////////////////////////////////////////////////////////////////////
10 void FileTimeoutHandler::timeoutExpired() noexcept
{
12 m_fileAwait
->setFinished(FileAwait::TIMEOUT
);
16 void FileEventHandler::handlerReady(uint16_t events
) noexcept
{
18 m_fileAwait
->setFinished(events
? FileAwait::READY
: FileAwait::CLOSED
);
22 /////////////////////////////////////////////////////////////////////////////
24 FileAwait::FileAwait(int fd
, uint16_t events
, double timeout
) {
26 assertx(events
& FileEventHandler::READ_WRITE
);
28 auto asio_event_base
= getSingleton
<AsioEventBase
>();
29 m_file
= std::make_shared
<FileEventHandler
>(asio_event_base
.get(), fd
, this);
30 m_file
->registerHandler(events
);
32 int64_t timeout_ms
= timeout
* 1000.0;
34 m_timeout
= std::make_shared
<FileTimeoutHandler
>(asio_event_base
.get(),
36 asio_event_base
->runInEventBaseThreadAndWait([this,timeout_ms
] {
38 m_timeout
->scheduleTimeout(timeout_ms
);
44 FileAwait::~FileAwait() {
46 // Avoid possible race condition
47 m_file
->m_fileAwait
= nullptr;
49 m_file
->unregisterHandler();
53 // Avoid race condition, we may (likely) finish destructing
54 // before the timeout cancels
55 m_timeout
->m_fileAwait
= nullptr;
57 auto to
= std::move(m_timeout
);
58 getSingleton
<AsioEventBase
>()->runInEventBaseThreadAndWait([to
] {
64 void FileAwait::unserialize(Cell
& c
) {
65 c
.m_type
= KindOfInt64
;
66 c
.m_data
.num
= m_result
;
69 void FileAwait::setFinished(int64_t status
) {
70 if (status
> m_result
) {
79 /////////////////////////////////////////////////////////////////////////////
81 Object
File::await(uint16_t events
, double timeout
) {
84 closedResult
.m_type
= KindOfInt64
;
85 closedResult
.m_data
.num
= FileAwait::CLOSED
;
86 return Object
{c_StaticWaitHandle::CreateSucceeded(closedResult
)};
89 SystemLib::throwExceptionObject(
90 "Unable to await on stream, invalid file descriptor");
92 events
= events
& FileEventHandler::READ_WRITE
;
94 SystemLib::throwExceptionObject(
95 "Must await for reading, writing, or both.");
98 auto ev
= new FileAwait(fd(), events
, timeout
);
100 return Object
{ev
->getWaitHandle()};
108 /////////////////////////////////////////////////////////////////////////////