Skip to content

Commit b378d8f

Browse files
committed
Fix tcore event loop timer writing to closed pipe
A delayed PostTask schedules a GLib timeout that writes to the wakeup pipe. The timeout was untracked, so one pending at destruction would fire after the loop closed pipe_fds_[1], writing to a closed or reused fd. Share a liveness flag with the timeout callback so it skips the write once the loop is destroyed.
1 parent b7371cc commit b378d8f

2 files changed

Lines changed: 16 additions & 6 deletions

File tree

flutter/shell/platform/tizen/tizen_event_loop.cc

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ TizenEventLoop::TizenEventLoop(std::thread::id main_thread_id,
3434
}
3535

3636
TizenEventLoop::~TizenEventLoop() {
37+
alive_->store(false);
3738
if (pipe_watch_id_ > 0) {
3839
g_source_remove(pipe_watch_id_);
3940
}
@@ -93,19 +94,23 @@ void TizenEventLoop::PostTask(FlutterTask flutter_task,
9394
const double flutter_duration =
9495
static_cast<double>(flutter_target_time_nanos) - get_current_time_();
9596
if (flutter_duration > 0) {
96-
int* pipe_write_fd = new int(pipe_fds_[1]);
97+
struct TimeoutContext {
98+
std::shared_ptr<std::atomic<bool>> alive;
99+
int fd;
100+
};
101+
auto* context = new TimeoutContext{alive_, pipe_fds_[1]};
97102
g_timeout_add(
98103
static_cast<guint>(flutter_duration / 1000000.0),
99104
[](gpointer data) -> gboolean {
100-
int* fd = static_cast<int*>(data);
101-
if (*fd >= 0) {
105+
auto* context = static_cast<TimeoutContext*>(data);
106+
if (context->alive->load() && context->fd >= 0) {
102107
char c = 1;
103-
write(*fd, &c, 1);
108+
write(context->fd, &c, 1);
104109
}
105-
delete fd;
110+
delete context;
106111
return G_SOURCE_REMOVE;
107112
},
108-
pipe_write_fd);
113+
context);
109114
} else {
110115
if (pipe_fds_[1] >= 0) {
111116
char c = 1;

flutter/shell/platform/tizen/tizen_event_loop.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <chrono>
1313
#include <deque>
1414
#include <functional>
15+
#include <memory>
1516
#include <mutex>
1617
#include <queue>
1718
#include <set>
@@ -77,6 +78,10 @@ class TizenEventLoop {
7778
int pipe_fds_[2] = {-1, -1};
7879
GIOChannel* pipe_channel_ = nullptr;
7980
guint pipe_watch_id_ = 0;
81+
// Shared with pending timeout callbacks so they can detect that this loop was
82+
// destroyed and skip writing to the (now closed) pipe.
83+
std::shared_ptr<std::atomic<bool>> alive_ =
84+
std::make_shared<std::atomic<bool>>(true);
8085

8186
// Returns a TaskTimePoint computed from the given target time from Flutter.
8287
TaskTimePoint TimePointFromFlutterTime(uint64_t flutter_target_time_nanos);

0 commit comments

Comments
 (0)