Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(38)

Unified Diff: native_client_sdk/src/libraries/ppapi_simple/ps_event.c

Issue 914983003: [NaCl SDK] Switch ppapi_simple to C library (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix tty output bug Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: native_client_sdk/src/libraries/ppapi_simple/ps_event.c
diff --git a/native_client_sdk/src/libraries/ppapi_simple/ps_event.c b/native_client_sdk/src/libraries/ppapi_simple/ps_event.c
new file mode 100644
index 0000000000000000000000000000000000000000..9d5199436e6ced445459339fb959b15b6eb90d6e
--- /dev/null
+++ b/native_client_sdk/src/libraries/ppapi_simple/ps_event.c
@@ -0,0 +1,271 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi_simple/ps_event.h"
+
+#include <assert.h>
+#include <pthread.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "ppapi_simple/ps_instance.h"
+#include "ppapi_simple/ps_interface.h"
+
+#define NO_BLOCK 0
+#define BLOCK 1
+
+struct PSMessageHandlerInfo {
+ char* message_name;
+ PSMessageHandler_t func;
+ void* user_data;
+ struct PSMessageHandlerInfo* prev;
+ struct PSMessageHandlerInfo* next;
+};
+
+static uint32_t s_events_enabled = PSE_NONE;
+static struct PSEvent* s_event_head;
+static struct PSEvent* s_event_tail;
+static pthread_mutex_t s_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t s_cond = PTHREAD_COND_INITIALIZER;
+static struct PSMessageHandlerInfo* s_handler_head;
+static struct PSMessageHandlerInfo* s_handler_tail;
+
+static struct PSMessageHandlerInfo* FindMessageHandler(
+ const char* message_name) {
+ struct PSMessageHandlerInfo* info = s_handler_head;
+ while (info) {
+ if (strcmp(info->message_name, message_name) == 0) {
+ return info;
+ }
+
+ info = info->next;
+ }
+
+ return NULL;
+}
+
+static void EnqueueEvent(struct PSEvent* event) {
+ pthread_mutex_lock(&s_lock);
+
+ if (!s_event_tail) {
+ s_event_head = s_event_tail = event;
+ event->next = NULL;
+ } else {
+ s_event_tail->next = event;
+ s_event_tail = event;
+ }
+
+ pthread_cond_signal(&s_cond);
+ pthread_mutex_unlock(&s_lock);
+}
+
+static struct PSEvent* DequeueEvent(int block) {
+ pthread_mutex_lock(&s_lock);
+
+ if (block) {
+ while (s_event_head == NULL) {
+ pthread_cond_wait(&s_cond, &s_lock);
+ }
+ }
+
+ if (s_event_head == NULL) {
+ pthread_mutex_unlock(&s_lock);
+ return NULL;
+ }
+
+ struct PSEvent* item = s_event_head;
+
+ if (s_event_head == s_event_tail) {
+ s_event_head = s_event_tail = NULL;
+ } else {
+ s_event_head = s_event_head->next;
+ }
+
+ pthread_mutex_unlock(&s_lock);
+
+ return item;
+}
+
+struct PSEvent* PSEventTryAcquire() {
+ struct PSEvent* event;
+ while (1) {
+ event = DequeueEvent(NO_BLOCK);
+ if (NULL == event)
+ break;
+ if (s_events_enabled & event->type)
+ break;
+ /* Release filtered events & continue to acquire. */
+ PSEventRelease(event);
+ }
+ return event;
+}
+
+struct PSEvent* PSEventWaitAcquire() {
+ struct PSEvent* event;
+ while (1) {
+ event = DequeueEvent(BLOCK);
+ if (s_events_enabled & event->type)
+ break;
+ /* Release filtered events & continue to acquire. */
+ PSEventRelease(event);
+ }
+ return event;
+}
+
+void PSEventRelease(struct PSEvent* event) {
+ if (event) {
+ switch (event->type) {
+ case PSE_INSTANCE_HANDLEMESSAGE:
+ PSInterfaceVar()->Release(event->as_var);
+ break;
+ case PSE_INSTANCE_HANDLEINPUT:
+ case PSE_INSTANCE_DIDCHANGEVIEW:
+ if (event->as_resource) {
+ PSInterfaceCore()->ReleaseResource(event->as_resource);
+ }
+ break;
+ default:
+ break;
+ }
+ free(event);
+ }
+}
+
+void PSEventSetFilter(PSEventTypeMask filter) {
+ s_events_enabled = filter;
+ if (filter == 0) {
+ static int s_warn_once = 1;
+ if (s_warn_once) {
+ PSInstanceWarn(
+ "PSInstance::SetEnabledEvents(mask) where mask == 0 will block\n");
+ PSInstanceWarn(
+ "all events. This can come from PSEventSetFilter(PSE_NONE);\n");
+ s_warn_once = 0;
+ }
+ }
+}
+
+void PSEventPost(PSEventType type) {
+ assert(PSE_GRAPHICS3D_GRAPHICS3DCONTEXTLOST == type ||
+ PSE_MOUSELOCK_MOUSELOCKLOST == type);
+
+ struct PSEvent* event = malloc(sizeof(struct PSEvent));
+ memset(event, 0, sizeof(*event));
+ event->type = type;
+ EnqueueEvent(event);
+}
+
+void PSEventPostBool(PSEventType type, PP_Bool bool_value) {
+ assert(PSE_INSTANCE_DIDCHANGEFOCUS == type);
+
+ struct PSEvent* event = malloc(sizeof(struct PSEvent));
+ memset(event, 0, sizeof(*event));
+ event->type = type;
+ event->as_bool = bool_value;
+ EnqueueEvent(event);
+}
+
+void PSEventPostVar(PSEventType type, struct PP_Var var) {
+ assert(PSE_INSTANCE_HANDLEMESSAGE == type);
+
+ /* If the message is a dictionary then see if it matches one of the specific
+ * handlers, then call that handler rather than queuing an event. */
+ if (var.type == PP_VARTYPE_DICTIONARY) {
+ struct PP_Var keys_var = PSInterfaceVarDictionary()->GetKeys(var);
+ if (PSInterfaceVarArray()->GetLength(keys_var) == 1) {
+ struct PP_Var key_var = PSInterfaceVarArray()->Get(keys_var, 0);
+ uint32_t key_len;
+ const char* key_str = PSInterfaceVar()->VarToUtf8(key_var, &key_len);
+ char* key_cstr = alloca(key_len + 1);
+ memcpy(key_cstr, key_str, key_len);
+ key_cstr[key_len] = 0;
+ PSInstanceTrace("calling handler for: %s\n", key_cstr);
+
+ struct PSMessageHandlerInfo* handler_info = FindMessageHandler(key_cstr);
+ if (handler_info) {
+ struct PP_Var value_var = PSInterfaceVarDictionary()->Get(var, key_var);
+ handler_info->func(key_var, value_var, handler_info->user_data);
+ PSInterfaceVar()->Release(value_var);
+ PSInterfaceVar()->Release(key_var);
+ PSInterfaceVar()->Release(keys_var);
+ return;
+ }
+
+ PSInterfaceVar()->Release(key_var);
+ }
+
+ PSInterfaceVar()->Release(keys_var);
+ }
+
+ PSInterfaceVar()->AddRef(var);
+ struct PSEvent *env = malloc(sizeof(struct PSEvent));
+ memset(env, 0, sizeof(*env));
+ env->type = type;
+ env->as_var = var;
+ EnqueueEvent(env);
+}
+
+void PSEventPostResource(PSEventType type, PP_Resource resource) {
+ assert(PSE_INSTANCE_HANDLEINPUT == type ||
+ PSE_INSTANCE_DIDCHANGEVIEW == type);
+
+ if (resource) {
+ PSInterfaceCore()->AddRefResource(resource);
+ }
+ struct PSEvent* event = malloc(sizeof(struct PSEvent));
+ memset(event, 0, sizeof(*event));
+ event->type = type;
+ event->as_resource = resource;
+ EnqueueEvent(event);
+}
+
+void PSEventRegisterMessageHandler(const char* message_name,
+ PSMessageHandler_t func,
+ void* user_data) {
+ PSInstanceTrace("registering msg handler: %s\n", message_name);
+ struct PSMessageHandlerInfo* handler = FindMessageHandler(message_name);
+
+ if (func == NULL) {
+ /* Unregister handler, if it exists */
+ if (handler) {
+ if (handler->prev) {
+ handler->prev->next = handler->next;
+ } else {
+ s_handler_head = handler->next;
+ }
+
+ if (handler->next) {
+ handler->next->prev = handler->prev;
+ } else {
+ s_handler_tail = handler->prev;
+ }
+
+ free(handler->message_name);
+ free(handler);
+ }
+ return;
+ }
+
+ if (handler) {
+ /* Already registered, change its function */
+ handler->func = func;
+ handler->user_data = user_data;
+ } else {
+ /* Not registered, append a new handler info */
+ struct PSMessageHandlerInfo* handler_info =
+ malloc(sizeof(struct PSMessageHandlerInfo));
+ handler_info->message_name = strdup(message_name);
+ handler_info->func = func;
+ handler_info->user_data = user_data;
+ handler_info->next = NULL;
+ handler_info->prev = s_handler_tail;
+
+ if (s_handler_tail) {
+ s_handler_tail->next = handler_info;
+ s_handler_tail = handler_info;
+ } else {
+ s_handler_head = s_handler_tail = handler_info;
+ }
+ }
+}
« no previous file with comments | « native_client_sdk/src/libraries/ppapi_simple/ps_event.h ('k') | native_client_sdk/src/libraries/ppapi_simple/ps_event.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698