Skip to content

Commit 766e177

Browse files
authored
Fix a crash when TizenVsyncWaiter is destroyed. (#15)
* Don't have vblank_ecore_pipe as a member anymore * Does not consider abnormal situations. This means, this situation should never happen. * Refactor TizenVsyncWaiter Signed-off-by: Boram Bae <[email protected]>
1 parent 67f0349 commit 766e177

File tree

4 files changed

+96
-114
lines changed

4 files changed

+96
-114
lines changed

shell/platform/tizen/tizen_embedder_engine.cc

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ TizenEmbedderEngine::TizenEmbedderEngine(
5656
message_dispatcher =
5757
std::make_unique<flutter::IncomingMessageDispatcher>(messenger.get());
5858

59-
tizen_vsync_waiter_ = std::make_unique<TizenVsyncWaiter>();
59+
tizen_vsync_waiter_ = std::make_unique<TizenVsyncWaiter>(this);
6060
}
6161

6262
TizenEmbedderEngine::~TizenEmbedderEngine() {
@@ -164,8 +164,6 @@ bool TizenEmbedderEngine::RunEngine(
164164
return false;
165165
}
166166

167-
tizen_vsync_waiter_->AsyncWaitForRunEngineSuccess(flutter_engine);
168-
169167
std::unique_ptr<FlutterTextureRegistrar> textures =
170168
std::make_unique<FlutterTextureRegistrar>();
171169
textures->flutter_engine = flutter_engine;
@@ -330,7 +328,11 @@ void TizenEmbedderEngine::OnFlutterPlatformMessage(
330328
void TizenEmbedderEngine::OnVsyncCallback(void* user_data, intptr_t baton) {
331329
TizenEmbedderEngine* tizen_embedder_engine =
332330
reinterpret_cast<TizenEmbedderEngine*>(user_data);
333-
tizen_embedder_engine->tizen_vsync_waiter_->AsyncWaitForVsync(baton);
331+
if (tizen_embedder_engine->tizen_vsync_waiter_->IsValid()) {
332+
tizen_embedder_engine->tizen_vsync_waiter_->AsyncWaitForVsync(baton);
333+
} else {
334+
LoggerW("TizenVsyncWaiter is not valid");
335+
}
334336
}
335337

336338
// Converts a FlutterPlatformMessage to an equivalent FlutterDesktopMessage.

shell/platform/tizen/tizen_surface_gl.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,7 @@ void* TizenSurfaceGL::OnProcResolver(const char* name) {
342342
GL_FUNC(glVertexAttrib4fv)
343343
GL_FUNC(glVertexAttribPointer)
344344
GL_FUNC(glViewport)
345-
LoggerW("Could not resolve: %s", name);
345+
LoggerD("Could not resolve: %s", name);
346346
return nullptr;
347347
}
348348
#undef GL_FUNC

shell/platform/tizen/tizen_vsync_waiter.cc

Lines changed: 76 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -4,65 +4,87 @@
44

55
#include "tizen_vsync_waiter.h"
66

7+
#include <Ecore.h>
8+
79
#include "flutter/shell/platform/tizen/logger.h"
10+
#include "flutter/shell/platform/tizen/tizen_embedder_engine.h"
11+
12+
static std::atomic<Ecore_Pipe*> g_vblank_ecore_pipe = nullptr;
813

9-
TizenVsyncWaiter::TizenVsyncWaiter()
10-
: client_(NULL),
11-
output_(NULL),
12-
vblank_(NULL),
13-
flutter_engine_(nullptr),
14-
baton_(0),
15-
vblank_ecore_pipe_(NULL) {
16-
if (CreateTDMVblank()) {
17-
std::thread t(CreateVblankEventLoop, this);
18-
t.join();
19-
} else {
20-
LoggerE("CreateVsyncVaiter fail");
14+
static const int VBLANK_LOOP_REQUEST = 1;
15+
static const int VBLANK_LOOP_DEL_PIPE = 2;
16+
17+
static void SendVblankLoopRequest(int event_type) {
18+
if (ecore_pipe_write(g_vblank_ecore_pipe.load(), &event_type,
19+
sizeof(event_type)) == EINA_FALSE) {
20+
LoggerE("Failed to Send Reqeust [%s]", event_type == VBLANK_LOOP_REQUEST
21+
? "VBLANK_LOOP_REQUEST"
22+
: "VBLANK_LOOP_DEL_PIPE");
2123
}
2224
}
2325

24-
void TizenVsyncWaiter::CreateVblankEventLoop(void* data) {
25-
TizenVsyncWaiter* tizen_vsync_waiter =
26-
reinterpret_cast<TizenVsyncWaiter*>(data);
27-
if (!ecore_init()) {
28-
LoggerE("ERROR: Cannot init Ecore!");
26+
TizenVsyncWaiter::TizenVsyncWaiter(TizenEmbedderEngine* engine)
27+
: engine_(engine) {
28+
if (!CreateTDMVblank()) {
29+
LoggerE("Failed to create TDM vblank");
2930
return;
3031
}
31-
tizen_vsync_waiter->vblank_ecore_pipe_ =
32-
ecore_pipe_add(VblankEventLoopCallback, tizen_vsync_waiter);
33-
LoggerD("ecore_init successful");
34-
ecore_main_loop_begin();
35-
ecore_shutdown();
36-
}
3732

38-
void TizenVsyncWaiter::VblankEventLoopCallback(void* data, void* buffer,
39-
unsigned int nbyte) {
40-
TizenVsyncWaiter* tizen_vsync_waiter =
41-
reinterpret_cast<TizenVsyncWaiter*>(data);
42-
int* event_type = reinterpret_cast<int*>(buffer);
43-
if ((*event_type) == VBLANK_LOOP_REQUEST) {
44-
tizen_vsync_waiter->AsyncWaitForVsyncCallback();
45-
} else if ((*event_type) == VBLANK_LOOP_DEL_PIPE) {
46-
tizen_vsync_waiter->DeleteVblankEventPipe();
33+
std::thread t(
34+
[this](void* data) {
35+
if (!ecore_init()) {
36+
LoggerE("Failed to init Ecore");
37+
return;
38+
}
39+
Ecore_Pipe* vblank_ecore_pipe = ecore_pipe_add(
40+
[](void* data, void* buffer, unsigned int nbyte) {
41+
TizenVsyncWaiter* tizen_vsync_waiter =
42+
reinterpret_cast<TizenVsyncWaiter*>(data);
43+
int event_type = *(reinterpret_cast<int*>(buffer));
44+
if (event_type == VBLANK_LOOP_REQUEST) {
45+
tizen_vsync_waiter->HandleVblankLoopRequest();
46+
} else if (event_type == VBLANK_LOOP_DEL_PIPE) {
47+
if (g_vblank_ecore_pipe.load()) {
48+
ecore_pipe_del(g_vblank_ecore_pipe);
49+
g_vblank_ecore_pipe = NULL;
50+
}
51+
ecore_main_loop_quit();
52+
}
53+
},
54+
this);
55+
56+
g_vblank_ecore_pipe.store(vblank_ecore_pipe);
57+
ecore_main_loop_begin();
58+
ecore_shutdown();
59+
},
60+
nullptr);
61+
t.join();
62+
63+
if (g_vblank_ecore_pipe.load() == nullptr) {
64+
LoggerE("Failed to create Ecore Pipe");
4765
}
4866
}
4967

50-
void TizenVsyncWaiter::AsyncWaitForVsyncCallback() {
51-
tdm_error ret;
52-
ret = tdm_client_vblank_wait(vblank_, 1, TdmClientVblankCallback, this);
53-
if (ret != TDM_ERROR_NONE) {
54-
LoggerE("ERROR, ret = %d", ret);
55-
return;
68+
TizenVsyncWaiter::~TizenVsyncWaiter() {
69+
if (g_vblank_ecore_pipe.load()) {
70+
SendVblankLoopRequest(VBLANK_LOOP_DEL_PIPE);
71+
}
72+
if (vblank_) {
73+
tdm_client_vblank_destroy(vblank_);
74+
}
75+
if (client_) {
76+
tdm_client_destroy(client_);
5677
}
57-
tdm_client_handle_events(client_);
5878
}
5979

60-
void TizenVsyncWaiter::DeleteVblankEventPipe() {
61-
if (vblank_ecore_pipe_) {
62-
ecore_pipe_del(vblank_ecore_pipe_);
63-
vblank_ecore_pipe_ = NULL;
64-
}
65-
ecore_main_loop_quit();
80+
void TizenVsyncWaiter::AsyncWaitForVsync(intptr_t baton) {
81+
baton_ = baton;
82+
SendVblankLoopRequest(VBLANK_LOOP_REQUEST);
83+
}
84+
85+
bool TizenVsyncWaiter::IsValid() {
86+
return g_vblank_ecore_pipe.load() && client_ && output_ && vblank_ &&
87+
engine_->flutter_engine;
6688
}
6789

6890
bool TizenVsyncWaiter::CreateTDMVblank() {
@@ -86,6 +108,7 @@ bool TizenVsyncWaiter::CreateTDMVblank() {
86108
}
87109

88110
tdm_client_vblank_set_enable_fake(vblank_, 1);
111+
89112
return true;
90113
}
91114

@@ -94,57 +117,20 @@ void TizenVsyncWaiter::TdmClientVblankCallback(
94117
unsigned int tv_sec, unsigned int tv_usec, void* user_data) {
95118
TizenVsyncWaiter* tizen_vsync_waiter =
96119
reinterpret_cast<TizenVsyncWaiter*>(user_data);
97-
if (tizen_vsync_waiter == nullptr) {
98-
LoggerE("tizen_vsync_waiter is null");
99-
return;
100-
}
101-
if (tizen_vsync_waiter->flutter_engine_ == nullptr) {
102-
LoggerI("flutter engine creation is not completed");
103-
return;
104-
}
120+
105121
uint64_t frame_start_time_nanos = tv_sec * 1e9 + tv_usec * 1e3;
106122
uint64_t frame_target_time_nanos = 16.6 * 1e6 + frame_start_time_nanos;
107-
FlutterEngineOnVsync(tizen_vsync_waiter->flutter_engine_,
123+
FlutterEngineOnVsync(tizen_vsync_waiter->engine_->flutter_engine,
108124
tizen_vsync_waiter->baton_, frame_start_time_nanos,
109125
frame_target_time_nanos);
110126
}
111127

112-
bool TizenVsyncWaiter::AsyncWaitForVsync() {
113-
if (nullptr == flutter_engine_) {
114-
LoggerD("flutter_engine_ is null");
115-
return false;
116-
}
117-
if (vblank_ecore_pipe_) {
118-
int event_type = VBLANK_LOOP_REQUEST;
119-
ecore_pipe_write(vblank_ecore_pipe_, &event_type, sizeof(event_type));
120-
}
121-
return true;
122-
}
123-
124-
TizenVsyncWaiter::~TizenVsyncWaiter() {
125-
if (vblank_ecore_pipe_) {
126-
int event_type = VBLANK_LOOP_DEL_PIPE;
127-
ecore_pipe_write(vblank_ecore_pipe_, &event_type, sizeof(event_type));
128-
}
129-
if (vblank_) {
130-
tdm_client_vblank_destroy(vblank_);
131-
}
132-
if (client_) {
133-
tdm_client_destroy(client_);
134-
}
135-
}
136-
137-
void TizenVsyncWaiter::AsyncWaitForVsync(intptr_t baton) {
138-
baton_ = baton;
139-
AsyncWaitForVsync();
140-
}
141-
142-
void TizenVsyncWaiter::AsyncWaitForRunEngineSuccess(
143-
FLUTTER_API_SYMBOL(FlutterEngine) flutter_engine) {
144-
flutter_engine_ = flutter_engine;
145-
if (baton_ == 0) {
146-
LoggerD("baton_ == 0");
128+
void TizenVsyncWaiter::HandleVblankLoopRequest() {
129+
tdm_error ret;
130+
ret = tdm_client_vblank_wait(vblank_, 1, TdmClientVblankCallback, this);
131+
if (ret != TDM_ERROR_NONE) {
132+
LoggerE("ERROR, ret = %d", ret);
147133
return;
148134
}
149-
AsyncWaitForVsync();
135+
tdm_client_handle_events(client_);
150136
}

shell/platform/tizen/tizen_vsync_waiter.h

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,41 +5,35 @@
55
#ifndef EMBEDDER_TIZEN_VSYNC_WAITER_H_
66
#define EMBEDDER_TIZEN_VSYNC_WAITER_H_
77

8-
#include <Ecore.h>
98
#include <tdm_client.h>
109

1110
#include <thread>
1211

1312
#include "flutter/shell/platform/embedder/embedder.h"
1413

14+
class TizenEmbedderEngine;
15+
1516
class TizenVsyncWaiter {
1617
public:
17-
TizenVsyncWaiter();
18+
TizenVsyncWaiter(TizenEmbedderEngine* engine);
1819
virtual ~TizenVsyncWaiter();
19-
bool CreateTDMVblank();
20-
bool AsyncWaitForVsync();
2120
void AsyncWaitForVsync(intptr_t baton);
22-
void AsyncWaitForRunEngineSuccess(FLUTTER_API_SYMBOL(FlutterEngine)
23-
flutter_engine);
21+
22+
bool IsValid();
2423

2524
private:
26-
static const int VBLANK_LOOP_REQUEST = 1;
27-
static const int VBLANK_LOOP_DEL_PIPE = 2;
28-
void AsyncWaitForVsyncCallback();
29-
void DeleteVblankEventPipe();
30-
static void CreateVblankEventLoop(void* data);
25+
bool CreateTDMVblank();
26+
void HandleVblankLoopRequest();
3127
static void TdmClientVblankCallback(tdm_client_vblank* vblank,
3228
tdm_error error, unsigned int sequence,
3329
unsigned int tv_sec, unsigned int tv_usec,
3430
void* user_data);
35-
static void VblankEventLoopCallback(void* data, void* buffer,
36-
unsigned int nbyte);
37-
tdm_client* client_;
38-
tdm_client_output* output_;
39-
tdm_client_vblank* vblank_;
40-
FLUTTER_API_SYMBOL(FlutterEngine) flutter_engine_;
41-
intptr_t baton_;
42-
Ecore_Pipe* vblank_ecore_pipe_;
31+
32+
tdm_client* client_{nullptr};
33+
tdm_client_output* output_{nullptr};
34+
tdm_client_vblank* vblank_{nullptr};
35+
TizenEmbedderEngine* engine_{nullptr};
36+
intptr_t baton_{0};
4337
};
4438

4539
#endif // EMBEDDER_TIZEN_VSYNC_WAITER_H_

0 commit comments

Comments
 (0)