Esempio n. 1
0
// Schedules task for execution on browser thread.
//
// Since there is no access to browser event loop, we start a nested event loop which is terminated
// as long as there is no tasks left. That way we can implement waiting as entering a nested loop
// and thus avoid deadlocks.
void
ppb_core_call_on_browser_thread(PP_Instance instance, void (*func)(void *), void *user_data)
{
    struct call_on_browser_thread_task_s *task = g_slice_alloc(sizeof(*task));
    task->func = func;
    task->user_data = user_data;

    // Push task into queue. The only purpose is to put task into queue even if message loop
    // is currenly terminating (in teardown state), so we are ignoring that. There are three
    // possible loop states. Message loop is either running, stopped, or terminating. If it's
    // still running, task will be executed in the context of that loop. If it's stopped or
    // stopping right now, task will be pushed to a queue. After that code below will schedule
    // nested loop on browser thread.
    PP_Resource m_loop = ppb_message_loop_get_for_browser_thread();
    ppb_message_loop_post_work_with_result(m_loop, PP_MakeCCB(call_on_browser_thread_comt, task), 0,
                                           PP_OK, 0, __func__);

    struct pp_instance_s *pp_i = instance ? tables_get_pp_instance(instance)
                                          : tables_get_some_pp_instance();
    if (!pp_i) {
        trace_error("%s, no alive instance available\n", __func__);
        return;
    }

    // Schedule activation routine.
    pthread_mutex_lock(&display.lock);
    if (pp_i->npp)
        npn.pluginthreadasynccall(pp_i->npp, activate_browser_thread_ml_ptac, user_data);
    pthread_mutex_unlock(&display.lock);
}
bool
p2n_get_property(NPObject *npobj, NPIdentifier name, NPVariant *np_result)
{
    if (!npn.identifierisstring(name)) {
        trace_error("%s, name is not a string\n", __func__);
        return false;
    }

    if (npobj->_class == &p2n_proxy_class) {
        struct get_property_param_s *p = g_slice_alloc(sizeof(*p));
        p->npobj =      npobj;
        p->name =       npn.utf8fromidentifier(name);
        p->np_result =  np_result;
        p->m_loop =     ppb_message_loop_get_for_browser_thread();
        p->depth =      ppb_message_loop_get_depth(p->m_loop) + 1;

        ppb_message_loop_post_work_with_result(p->m_loop,
                                               PP_MakeCCB(p2n_get_property_prepare_comt, p), 0,
                                               PP_OK, 0, __func__);
        ppb_message_loop_run_nested(p->m_loop);
        bool result = p->result;
        npn.memfree(p->name);
        g_slice_free1(sizeof(*p), p);
        return result;
    } else {
        return npobj->_class->getProperty(npobj, name, np_result);
    }
}
Esempio n. 3
0
static
int
call_plugin_init_module(void)
{
    int32_t   (*ppp_initialize_module)(PP_Module module_id, PPB_GetInterface get_browser_interface);

    if (!module_dl_handler)
        return 0;

    ppp_initialize_module = dlsym(module_dl_handler, "PPP_InitializeModule");
    if (!ppp_initialize_module)
        return 0;

    struct call_plugin_init_module_param_s *p = g_slice_alloc(sizeof(*p));
    p->m_loop =                ppb_message_loop_get_for_browser_thread();
    p->depth =                 ppb_message_loop_get_depth(p->m_loop) + 1;
    p->ppp_initialize_module = ppp_initialize_module;

    ppb_message_loop_post_work_with_result(p->m_loop,
                                           PP_MakeCCB(call_plugin_init_module_prepare_comt, p), 0,
                                           PP_OK, p->depth, __func__);
    ppb_message_loop_run_nested(p->m_loop);
    int res = p->result;
    g_slice_free1(sizeof(*p), p);

    return res;
}
Esempio n. 4
0
static
void
activate_browser_thread_ml_ptac(void *param)
{
    // If task was already executed and queue is empty, ppb_message_loop_run_int() will return
    // without waiting.
    PP_Resource m_loop = ppb_message_loop_get_for_browser_thread();
    ppb_message_loop_run_int(m_loop, ML_INCREASE_DEPTH | ML_EXIT_ON_EMPTY | ML_NESTED);
}
bool
p2n_enumerate(NPObject *npobj, NPIdentifier **value, uint32_t *count)
{
    if (npobj->_class == &p2n_proxy_class) {
        struct enumerate_param_s *p = g_slice_alloc(sizeof(*p));
        p->npobj =      npobj;
        p->m_loop =     ppb_message_loop_get_for_browser_thread();
        p->depth =      ppb_message_loop_get_depth(p->m_loop) + 1;

        ppb_message_loop_post_work_with_result(p->m_loop, PP_MakeCCB(p2n_enumerate_prepare_comt, p),
                                               0, PP_OK, 0, __func__);
        ppb_message_loop_run_nested(p->m_loop);
        bool result = p->result;
        *count = p->count;

        *value = npn.memalloc(p->count * sizeof(NPIdentifier));
        char *tmpbuf = malloc(1);
        for (uint32_t k = 0; k < p->count; k ++) {
            uint32_t len = 0;
            const char *s = ppb_var_var_to_utf8(p->values[k], &len);

            // make zero-terminated string
            char *ptr = realloc(tmpbuf, len + 1);
            if (!ptr) {
                result = false;
                goto err;
            }
            tmpbuf = ptr;
            memcpy(tmpbuf, s, len);
            tmpbuf[len] = 0;
            value[k] = npn.getstringidentifier(tmpbuf);
        }

    err:
        free(tmpbuf);
        g_slice_free1(sizeof(*p), p);

        return result;
    } else {
        return npobj->_class->enumerate(npobj, value, count);
    }
}
Esempio n. 6
0
static
void
call_plugin_shutdown_module(void)
{
    if (!module_dl_handler)
        return;

    void (*ppp_shutdown_module)(void);
    ppp_shutdown_module = dlsym(module_dl_handler, "PPP_ShutdownModule");
    if (!ppp_shutdown_module)
        return;

    struct call_plugin_shutdown_module_param_s *p = g_slice_alloc(sizeof(*p));
    p->m_loop =              ppb_message_loop_get_for_browser_thread();
    p->depth =               ppb_message_loop_get_depth(p->m_loop) + 1;
    p->ppp_shutdown_module = ppp_shutdown_module;

    ppb_message_loop_post_work_with_result(p->m_loop,
                                           PP_MakeCCB(call_plugin_shutdown_module_prepare_comt, p),
                                           0, PP_OK, p->depth, __func__);
    ppb_message_loop_run_nested(p->m_loop);
    g_slice_free1(sizeof(*p), p);
}