| Index: src/untrusted/nacl/nacl_irt_module.c
|
| diff --git a/src/untrusted/nacl/nacl_irt_module.c b/src/untrusted/nacl/nacl_irt_module.c
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..f7db0ef869668d415e97d6c29539734b663085cd
|
| --- /dev/null
|
| +++ b/src/untrusted/nacl/nacl_irt_module.c
|
| @@ -0,0 +1,234 @@
|
| +/*
|
| + * Copyright (c) 2013 The Native Client 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 "native_client/src/untrusted/nacl/nacl_irt_module.h"
|
| +
|
| +#include <errno.h>
|
| +#include <pthread.h>
|
| +#include <stdio.h>
|
| +#include <stdlib.h>
|
| +#include <string.h>
|
| +#include <unistd.h>
|
| +
|
| +#include "native_client/src/untrusted/nacl/nacl_irt.h"
|
| +
|
| +/*static pthread_key_t nacl_irt_context_key;*/
|
| +/*static pthread_mutex_t nacl_irt_context_lock = PTHREAD_MUTEX_INITIALIZER;*/
|
| +static int nacl_irt_context_ref;
|
| +static struct nacl_irt_module *nacl_irt_modules;
|
| +static struct nacl_irt_context context;
|
| +
|
| +struct nacl_irt_context *nacl_irt_get_context(void) {
|
| + return (struct nacl_irt_context *) &context; /*pthread_getspecific(nacl_irt_context_key);*/
|
| +}
|
| +
|
| +/*
|
| +static struct nacl_irt_context *nacl_irt_create_context(struct nacl_irt *irt) {
|
| + struct nacl_irt_context *ctx = nacl_irt_get_context();
|
| +
|
| + if (NULL == ctx) {
|
| + ctx = (struct nacl_irt_context *) malloc(sizeof *ctx);
|
| + if (NULL == ctx) {
|
| + fprintf(stderr, "irt: failed to allocate thread specific data\n");
|
| + abort();
|
| + }
|
| + pthread_setspecific(nacl_irt_context_key, ctx);
|
| + } else {
|
| + memset(ctx, 0, sizeof *ctx);
|
| + }
|
| + ctx->irt = irt;
|
| +
|
| + return ctx;
|
| +}
|
| +*/
|
| +/*
|
| +static void nacl_irt_free_context(void *data) {
|
| + free(data);
|
| +}
|
| +*/
|
| +
|
| +static int nacl_irt_create_context_key(void) {
|
| + int err = 0;
|
| +
|
| + /*pthread_mutex_lock(&nacl_irt_context_lock);*/
|
| + if (0 != nacl_irt_context_ref) {
|
| + err = 0;
|
| + /*pthread_key_create(&nacl_irt_context_key, nacl_irt_free_context);*/
|
| + if (0 != err) {
|
| + fprintf(stderr, "irt: failed to create thread specific key: %s\n",
|
| + strerror(err));
|
| + goto out;
|
| + }
|
| + }
|
| + nacl_irt_context_ref++;
|
| +out:
|
| + /*pthread_mutex_unlock(&nacl_irt_context_lock);*/
|
| + return err;
|
| +}
|
| +
|
| +static void nacl_irt_delete_context_key(void) {
|
| + /*pthread_mutex_lock(&nacl_irt_context_lock);*/
|
| + if (0 != nacl_irt_context_ref) {
|
| + }
|
| + /*pthread_mutex_unlock(&nacl_irt_context_lock);*/
|
| +}
|
| +
|
| +void nacl_irt_layer_init(struct nacl_irt_layer *layer) {
|
| + struct nacl_irt_instance irt_instance;
|
| +
|
| + fprintf(stderr, "query %p\n", __nacl_irt_query);
|
| + /*nacl_irt_get_context()->private_data = layer->user_data;*/
|
| + if (layer->irt_query(NACL_IRT_INSTANCE_v0_1, &irt_instance,
|
| + sizeof(irt_instance)) != sizeof(irt_instance)) {
|
| + static const char fail_msg[] =
|
| + "query failed for essential interface \""NACL_IRT_INSTANCE_v0_1 "\"\n";
|
| + write(2, fail_msg, sizeof(fail_msg) - 1);
|
| + _exit(-1);
|
| + }
|
| +
|
| + fprintf(stderr, "init = %p\n", irt_instance.init);
|
| + irt_instance.init();
|
| + /* if(!layer->interfaces.init(x, &layer->user_data)) {} */
|
| +}
|
| +
|
| +void nacl_irt_layer_destroy(struct nacl_irt_layer *layer) {
|
| + nacl_irt_get_context()->private_data = layer->user_data;
|
| + /* layer->user_data = layer->interfaces.destroy(); */
|
| + free(layer);
|
| +}
|
| +
|
| +static struct nacl_irt_module *nacl_irt_find_module(const char *name) {
|
| + struct nacl_irt_module *module = NULL;
|
| +
|
| + for (module = nacl_irt_modules; NULL != module; module = module->next) {
|
| + if (0 == strcmp(name, module->name)) {
|
| + break;
|
| + }
|
| + }
|
| + return module;
|
| +}
|
| +
|
| +static struct nacl_irt_module *nacl_irt_get_module(const char *name) {
|
| + struct nacl_irt_module *module;
|
| +
|
| + /*pthread_mutex_lock(&nacl_irt_context_lock);*/
|
| + module = nacl_irt_find_module(name);
|
| + /*pthread_mutex_unlock(&nacl_irt_context_lock);*/
|
| + return module;
|
| +}
|
| +
|
| +static int nacl_irt_load_module(struct nacl_irt *irt, const char *name, struct nacl_irt_args *args) {
|
| + struct nacl_irt_layer *layers[2] = { irt->layer, NULL };
|
| + struct nacl_irt_layer *new_layer;
|
| + struct nacl_irt_module *module = nacl_irt_get_module(name);
|
| +
|
| + if (NULL == module) {
|
| + return -1;
|
| + }
|
| +
|
| + new_layer = module->factory(args, layers);
|
| + if (NULL == new_layer) {
|
| + return -1;
|
| + }
|
| +
|
| + new_layer->module = module;
|
| + irt->layer = new_layer;
|
| +
|
| + return 0;
|
| +}
|
| +
|
| +struct nacl_irt_layer *nacl_irt_layer_new(/*const struct nacl_irt_interface *itf,*/
|
| + /*size_t itf_size,*/
|
| + TYPE_nacl_irt_query query,
|
| + void *user_data) {
|
| + struct nacl_irt_layer *layer;
|
| +
|
| + layer = (struct nacl_irt_layer *) malloc(sizeof *layer);
|
| + if (NULL == layer) {
|
| + fprintf(stderr, "irt: failed to allocate layer\n");
|
| + return NULL;
|
| + }
|
| +
|
| + layer->user_data = user_data;
|
| + if (NULL != query) {
|
| + /*memcpy(&layer->interfaces, interfaces, interfaces_size);*/
|
| + /*layer->interfaces = (struct nacl_irt_interface *) itf;*/
|
| + layer->irt_query = query;
|
| + }
|
| + return layer;
|
| +}
|
| +
|
| +struct nacl_irt *nacl_irt_new(struct nacl_irt_args *args,
|
| + TYPE_nacl_irt_query query,
|
| + /*const struct nacl_irt_interface *itf,*/
|
| + /*size_t itf_size,*/
|
| + void *user_data) {
|
| + struct nacl_irt *irt;
|
| + struct nacl_irt_layer *layer;
|
| +
|
| + if (-1 == nacl_irt_create_context_key()) {
|
| + fprintf(stderr, "irt: failed to create context key\n");
|
| + goto out;
|
| + }
|
| +
|
| + irt = (struct nacl_irt *) malloc(sizeof *irt);
|
| + if (NULL == irt) {
|
| + fprintf(stderr, "irt: failed to allocate irt\n");
|
| + goto out_delete_context_key;
|
| + }
|
| +
|
| + fprintf(stderr, "in: %p\n", query);
|
| +
|
| + layer = nacl_irt_layer_new(query, user_data);
|
| + /*layer = nacl_irt_layer_new(itf, itf_size, user_data);*/
|
| + if (NULL == layer) {
|
| + fprintf(stderr, "irt: failed to allocate layer\n");
|
| + goto out_free;
|
| + }
|
| +
|
| + irt->layer = layer;
|
| +
|
| + /*
|
| + * if (nacl_irt_opt_parse(args, &irt->conf, irt_lib_opts,
|
| + * irt_lib_opt_proc) == -1) {
|
| + * goto out_free;
|
| + * }
|
| + */
|
| +
|
| + {
|
| + const char *modules[] = { "irt_trace", NULL };
|
| + const char **module;
|
| + for (module = &modules[0]; *module; module++) {
|
| + if (-1 == nacl_irt_load_module(irt, *module, args)) {
|
| + goto out_free;
|
| + }
|
| + }
|
| + }
|
| +
|
| + return irt;
|
| +
|
| +out_free:
|
| + free(irt);
|
| +out_delete_context_key:
|
| + nacl_irt_delete_context_key();
|
| +out:
|
| + return NULL;
|
| +}
|
| +
|
| +void nacl_irt_register_module(struct nacl_irt_module *module) {
|
| + fprintf(stderr, "register\n");
|
| + module->next = nacl_irt_modules;
|
| + nacl_irt_modules = module;
|
| +}
|
| +
|
| +typedef int (*TYPE_nacl_irt_module)(int argc, char **argv);
|
| +
|
| +void __libnacl_irt_register_module(struct nacl_irt_module *module) {
|
| + fprintf(stderr, "register\n");
|
| + module->next = nacl_irt_modules;
|
| + module->factory(
|
| + nacl_irt_modules = module;
|
| +}
|
|
|