summaryrefslogtreecommitdiffstats
path: root/native_client_sdk
diff options
context:
space:
mode:
authornfullagar@chromium.org <nfullagar@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-08-02 23:10:00 +0000
committernfullagar@chromium.org <nfullagar@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-08-02 23:10:00 +0000
commitd9bd64662ea5846792505e1b94b9f7b8ead62e9e (patch)
treed0bf152b5377bdc95d9e7adf9a4e05587177de1e /native_client_sdk
parent1d5344cb344def3e530c8dcac6f50bb1da45e64e (diff)
downloadchromium_src-d9bd64662ea5846792505e1b94b9f7b8ead62e9e.zip
chromium_src-d9bd64662ea5846792505e1b94b9f7b8ead62e9e.tar.gz
chromium_src-d9bd64662ea5846792505e1b94b9f7b8ead62e9e.tar.bz2
Fix event race in ppapi simple framework.
By default, all events are filtered out between the main thread and the application thread in ppapi simple. Events are filtered out before inserting them into the FIFO queue between the threads. In some cases, an app that enables PSEventSetFilter(PSE_ALL) will miss the first few events. This change pushes all events into the FIFO queue, and does filtering when extracting them on the app thread. While not ideal, it addresses the problem of an app potentially missing the first few events, which if they are DidChangeView or a message from JS could prevent the app from starting correctly. BUG=263248 TEST=try bots, manually run examples in SDK R=noelallen@chromium.org Review URL: https://codereview.chromium.org/20006005 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@215395 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'native_client_sdk')
-rw-r--r--native_client_sdk/src/libraries/ppapi_simple/ps_instance.cc82
1 files changed, 50 insertions, 32 deletions
diff --git a/native_client_sdk/src/libraries/ppapi_simple/ps_instance.cc b/native_client_sdk/src/libraries/ppapi_simple/ps_instance.cc
index 711c119..c14b8ac 100644
--- a/native_client_sdk/src/libraries/ppapi_simple/ps_instance.cc
+++ b/native_client_sdk/src/libraries/ppapi_simple/ps_instance.cc
@@ -266,46 +266,48 @@ void PSInstance::Error(const char *fmt, ...) {
void PSInstance::SetEnabledEvents(uint32_t mask) {
events_enabled_ = mask;
+ if (mask == 0) {
+ static bool warn_once = true;
+ if (warn_once) {
+ Warn("PSInstance::SetEnabledEvents(mask) where mask == 0 will block\n");
+ Warn("all events. This can come from PSEventSetFilter(PSE_NONE);\n");
+ warn_once = false;
+ }
+ }
}
void PSInstance::PostEvent(PSEventType type) {
assert(PSE_GRAPHICS3D_GRAPHICS3DCONTEXTLOST == type ||
PSE_MOUSELOCK_MOUSELOCKLOST == type);
- if (events_enabled_ & type) {
- PSEvent *env = (PSEvent *) malloc(sizeof(PSEvent));
- memset(env, 0, sizeof(*env));
- env->type = type;
- event_queue_.Enqueue(env);
- }
+ PSEvent *env = (PSEvent *) malloc(sizeof(PSEvent));
+ memset(env, 0, sizeof(*env));
+ env->type = type;
+ event_queue_.Enqueue(env);
}
void PSInstance::PostEvent(PSEventType type, PP_Bool bool_value) {
assert(PSE_INSTANCE_DIDCHANGEFOCUS == type);
- if (events_enabled_ & type) {
- PSEvent *env = (PSEvent *) malloc(sizeof(PSEvent));
- memset(env, 0, sizeof(*env));
- env->type = type;
- env->as_bool = bool_value;
- event_queue_.Enqueue(env);
- }
+ PSEvent *env = (PSEvent *) malloc(sizeof(PSEvent));
+ memset(env, 0, sizeof(*env));
+ env->type = type;
+ env->as_bool = bool_value;
+ event_queue_.Enqueue(env);
}
void PSInstance::PostEvent(PSEventType type, PP_Resource resource) {
assert(PSE_INSTANCE_HANDLEINPUT == type ||
PSE_INSTANCE_DIDCHANGEVIEW == type);
- if (events_enabled_ & type) {
- if (resource) {
- PSInterfaceCore()->AddRefResource(resource);
- }
- PSEvent *env = (PSEvent *) malloc(sizeof(PSEvent));
- memset(env, 0, sizeof(*env));
- env->type = type;
- env->as_resource = resource;
- event_queue_.Enqueue(env);
+ if (resource) {
+ PSInterfaceCore()->AddRefResource(resource);
}
+ PSEvent *env = (PSEvent *) malloc(sizeof(PSEvent));
+ memset(env, 0, sizeof(*env));
+ env->type = type;
+ env->as_resource = resource;
+ event_queue_.Enqueue(env);
}
void PSInstance::PostEvent(PSEventType type, const PP_Var& var) {
@@ -335,22 +337,38 @@ void PSInstance::PostEvent(PSEventType type, const PP_Var& var) {
return;
}
- if (events_enabled_ & type) {
- PSInterfaceVar()->AddRef(var);
- PSEvent *env = (PSEvent *) malloc(sizeof(PSEvent));
- memset(env, 0, sizeof(*env));
- env->type = type;
- env->as_var = var;
- event_queue_.Enqueue(env);
- }
+ PSInterfaceVar()->AddRef(var);
+ PSEvent *env = (PSEvent *) malloc(sizeof(PSEvent));
+ memset(env, 0, sizeof(*env));
+ env->type = type;
+ env->as_var = var;
+ event_queue_.Enqueue(env);
}
PSEvent* PSInstance::TryAcquireEvent() {
- return event_queue_.Dequeue(false);
+ PSEvent* event;
+ while(true) {
+ event = event_queue_.Dequeue(false);
+ if (NULL == event)
+ break;
+ if (events_enabled_ & event->type)
+ break;
+ // Release filtered events & continue to acquire.
+ ReleaseEvent(event);
+ }
+ return event;
}
PSEvent* PSInstance::WaitAcquireEvent() {
- return event_queue_.Dequeue(true);
+ PSEvent* event;
+ while(true) {
+ event = event_queue_.Dequeue(true);
+ if (events_enabled_ & event->type)
+ break;
+ // Release filtered events & continue to acquire.
+ ReleaseEvent(event);
+ }
+ return event;
}
void PSInstance::ReleaseEvent(PSEvent* event) {