blob: 49f83ff3462c967f141bd0e9f19765a9061f8898 [file] [log] [blame]
Yifan Hong8c950422021-08-05 17:13:55 -07001/*
2 * Copyright (C) 2021 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "FdTrigger"
18#include <log/log.h>
19
20#include <poll.h>
21
22#include <android-base/macros.h>
23
24#include "FdTrigger.h"
25namespace android {
26
27std::unique_ptr<FdTrigger> FdTrigger::make() {
28 auto ret = std::make_unique<FdTrigger>();
29 if (!android::base::Pipe(&ret->mRead, &ret->mWrite)) {
30 ALOGE("Could not create pipe %s", strerror(errno));
31 return nullptr;
32 }
33 return ret;
34}
35
36void FdTrigger::trigger() {
37 mWrite.reset();
38}
39
40bool FdTrigger::isTriggered() {
41 return mWrite == -1;
42}
43
44status_t FdTrigger::triggerablePoll(base::borrowed_fd fd, int16_t event) {
45 while (true) {
46 pollfd pfd[]{{.fd = fd.get(), .events = static_cast<int16_t>(event), .revents = 0},
Yifan Hong8cbe66b2021-08-10 14:49:07 -070047 {.fd = mRead.get(), .events = 0, .revents = 0}};
Yifan Hong8c950422021-08-05 17:13:55 -070048 int ret = TEMP_FAILURE_RETRY(poll(pfd, arraysize(pfd), -1));
49 if (ret < 0) {
50 return -errno;
51 }
52 if (ret == 0) {
53 continue;
54 }
55 if (pfd[1].revents & POLLHUP) {
Steven Morelandc591b472021-09-16 13:56:11 -070056 return DEAD_OBJECT;
Yifan Hong8c950422021-08-05 17:13:55 -070057 }
58 return pfd[0].revents & event ? OK : DEAD_OBJECT;
59 }
60}
61
Yifan Hong8c950422021-08-05 17:13:55 -070062} // namespace android