Exemplo n.º 1
0
static bool
_CatalogRemoveToken(_Catalog *catalog, const char *token,
                    bool notify)
{
    _Subscription *subs = _SubscriptionAcquire(catalog, token);
    if (!subs) return false;

    if (notify && catalog->cancel_function)
    {
        catalog->cancel_function(catalog->sh,
                                 subs->message, catalog->cancel_function_ctx);
    }

    _CatalogLock(catalog);
    int i;
    // Remove subscription from key sublists
    for (i = 0; i < subs->keys->len; i++)
    {
        const char *key = g_ptr_array_index(subs->keys, i);

        _SubList *sub_list =
            g_hash_table_lookup(catalog->subscription_lists, key);

        _SubListRemove(sub_list, token);

        if (_SubListLen(sub_list) == 0)
        {
            g_hash_table_remove(catalog->subscription_lists, key);
        }
    }

    // Remove subscrition from client subscription list
    const char *client_name = LSMessageGetSender(subs->message);
    _SubList *client_sub_list =
        g_hash_table_lookup(catalog->client_subscriptions, client_name);

    _SubListRemove(client_sub_list, token);

    if (_SubListLen(client_sub_list) == 0)
    {
        g_hash_table_remove(catalog->client_subscriptions, client_name);
    }

    _CatalogUnlock(catalog);

    _SubscriptionRemove(catalog, subs, token);

    _SubscriptionRelease(catalog, subs);

    return true;
}
Exemplo n.º 2
0
/** 
* @brief Returns a string that uniquely represents this message. 
* 
* @param  message 
* 
* @retval
*/
const char *
LSMessageGetUniqueToken(LSMessage *message)
{
    if (!message)
        return NULL;

    if (message->uniqueTokenAllocated)
        return message->uniqueTokenAllocated;

    const char *sender = LSMessageGetSender(message);
    LSMessageToken token = LSMessageGetToken(message);

    message->uniqueTokenAllocated = g_strdup_printf("%s.%ld", sender, token);

    return message->uniqueTokenAllocated;
}
Exemplo n.º 3
0
bool
_CatalogHandleCancel(_Catalog *catalog, LSMessage *cancelMsg,
                     LSError *lserror)
{
    JSchemaInfo schemaInfo;
    jschema_info_init(&schemaInfo, jschema_all(), NULL, NULL);

    const char *sender;
    int token;
    jvalue_ref tokenObj = NULL;

    const char *payload = LSMessageGetPayload(cancelMsg);

    jvalue_ref object = jdom_parse(j_cstr_to_buffer(payload), DOMOPT_NOOPT,
                                   &schemaInfo);
    if (jis_null(object))
    {
        _LSErrorSet(lserror, MSGID_LS_INVALID_JSON, -EINVAL, "Invalid json");
        goto error;
    }

    sender = LSMessageGetSender(cancelMsg);

    if (!jobject_get_exists(object, J_CSTR_TO_BUF("token"), &tokenObj) ||
            tokenObj == NULL || !jis_number(tokenObj))
    {
        _LSErrorSet(lserror, MSGID_LS_INVALID_JSON, -EINVAL, "Invalid json");
        goto error;
    }

    (void)jnumber_get_i32(tokenObj, &token);/* TODO: handle appropriately */

    char *uniqueToken = g_strdup_printf("%s.%d", sender, token);

    _CatalogCallCancelNotifications(catalog, uniqueToken);
    _CatalogRemoveToken(catalog, uniqueToken, true);

    g_free(uniqueToken);
    j_release(&object);
    return true;

error:
    j_release(&object);
    return false;
}
Exemplo n.º 4
0
bool
_LSPrivateGetSubscriptions(LSHandle* sh, LSMessage *message, void *ctx)
{
    LSError lserror;
    LSErrorInit(&lserror);

    const char *sender = LSMessageGetSenderServiceName(message);

    if (!sender || strcmp(sender, MONITOR_NAME) != 0)
    {
        g_critical("WARNING: subscription debug method not called by monitor;"
                   " ignoring (service name: %s, unique_name: %s)",
                   sender, LSMessageGetSender(message));
        return true;
    }

    struct json_object *ret_obj = NULL;
    bool json_ret = _LSSubscriptionGetJson(sh, &ret_obj, &lserror);
    if (!json_ret)
    {
        LSErrorPrint(&lserror, stderr);
        LSErrorFree(&lserror);
        return true;
    }

    bool reply_ret = LSMessageReply(sh, message, json_object_to_json_string(ret_obj), &lserror);
    if (!reply_ret)
    {
        g_critical("%s: sending subscription info failed", __FUNCTION__);
        LSErrorPrint(&lserror, stderr);
        LSErrorFree(&lserror);
    }

    json_object_put(ret_obj);
    
    return true;

}
Exemplo n.º 5
0
bool
_LSPrivateGetMallinfo(LSHandle* sh, LSMessage *message, void *ctx)
{
    LSError lserror;
    LSErrorInit(&lserror);

    struct json_object *ret_obj = NULL;
    struct json_object *true_obj = NULL;
    struct json_object *mallinfo_obj = NULL;
    struct json_object *allocator_name_obj = NULL;
    struct json_object *slot_a_obj = NULL;
    struct json_object *slot_d_obj = NULL;
    struct json_object *slot_e_obj = NULL;
    struct json_object *slot_f_obj = NULL;
    struct json_object *slot_h_obj = NULL;
    struct json_object *slot_i_obj = NULL;
    struct json_object *slot_j_obj = NULL;

    const char *sender = LSMessageGetSenderServiceName(message);

    if (!sender || strcmp(sender, MONITOR_NAME) != 0)
    {
        g_critical("WARNING: mallinfo debug method not called by monitor;"
                   " ignoring (service name: %s, unique_name: %s)",
                   sender, LSMessageGetSender(message));
        return true;
    }

    ret_obj = json_object_new_object();
    if (JSON_ERROR(ret_obj)) goto error;
       
    true_obj = json_object_new_boolean(true);
    if (JSON_ERROR(true_obj)) goto error;
 
    mallinfo_obj = json_object_new_object();
    if (JSON_ERROR(mallinfo_obj)) goto error;

    /* returnValue: true,
     * mallinfo: {key: int,...}
     */

    typedef struct mallinfo (*mallinfo_t)();
    static mallinfo_t mallinfo_p = NULL;

    if (mallinfo_p == NULL) {
        mallinfo_p = (mallinfo_t)dlsym(RTLD_DEFAULT, "mallinfo");
        if (mallinfo_p == NULL)
            mallinfo_p = (mallinfo_t)-1;
    }
    struct mallinfo mi;
    if (mallinfo_p != (mallinfo_t)-1) {
        mi = mallinfo_p();
    } else {
        memset(&mi, '\0', sizeof(mi));
    }
    
    allocator_name_obj = json_object_new_string("ptmalloc");
    if (JSON_ERROR(allocator_name_obj)) goto error;

    slot_a_obj = json_object_new_int(mi.arena);
    if (JSON_ERROR(slot_a_obj)) goto error;

    slot_d_obj = json_object_new_int(mi.hblks);
    if (JSON_ERROR(slot_d_obj)) goto error;

    slot_e_obj = json_object_new_int(mi.hblkhd);
    if (JSON_ERROR(slot_e_obj)) goto error;

    slot_f_obj = json_object_new_int(mi.usmblks);
    if (JSON_ERROR(slot_f_obj)) goto error;

    slot_h_obj = json_object_new_int(mi.uordblks);
    if (JSON_ERROR(slot_h_obj)) goto error;

    slot_i_obj = json_object_new_int(mi.fordblks);
    if (JSON_ERROR(slot_i_obj)) goto error;
    
    slot_j_obj = json_object_new_int(mi.keepcost);
    if (JSON_ERROR(slot_j_obj)) goto error;

    json_object_object_add(mallinfo_obj, "allocator", allocator_name_obj);
    json_object_object_add(mallinfo_obj, "sbrk_bytes", slot_a_obj);
    json_object_object_add(mallinfo_obj, "mmap_count", slot_d_obj);
    json_object_object_add(mallinfo_obj, "mmap_bytes", slot_e_obj);
    json_object_object_add(mallinfo_obj, "max_malloc_bytes", slot_f_obj);
    json_object_object_add(mallinfo_obj, "malloc_bytes", slot_h_obj);
    json_object_object_add(mallinfo_obj, "slack_bytes", slot_i_obj);
    json_object_object_add(mallinfo_obj, "trimmable_slack_bytes", slot_j_obj);
        
    json_object_object_add(ret_obj, "returnValue", true_obj);
    json_object_object_add(ret_obj, "mallinfo", mallinfo_obj);

    bool reply_ret = LSMessageReply(sh, message, json_object_to_json_string(ret_obj), &lserror);
    if (!reply_ret)
    {
        g_critical("%s: sending malloc info failed", __FUNCTION__);
        LSErrorPrint(&lserror, stderr);
        LSErrorFree(&lserror);
    }

    json_object_put(ret_obj);
    
    return true;

error:
    
    if (!JSON_ERROR(ret_obj)) json_object_put(ret_obj);
    if (!JSON_ERROR(true_obj)) json_object_put(true_obj);
    if (!JSON_ERROR(mallinfo_obj)) json_object_put(mallinfo_obj);
    
    if (!JSON_ERROR(allocator_name_obj)) json_object_put(allocator_name_obj);
    if (!JSON_ERROR(slot_a_obj)) json_object_put(slot_a_obj);
    if (!JSON_ERROR(slot_d_obj)) json_object_put(slot_d_obj);
    if (!JSON_ERROR(slot_e_obj)) json_object_put(slot_e_obj);
    if (!JSON_ERROR(slot_f_obj)) json_object_put(slot_f_obj);
    if (!JSON_ERROR(slot_h_obj)) json_object_put(slot_h_obj);
    if (!JSON_ERROR(slot_i_obj)) json_object_put(slot_i_obj);
    if (!JSON_ERROR(slot_j_obj)) json_object_put(slot_j_obj);
    
    return true;
}
Exemplo n.º 6
0
bool
_LSSubscriptionGetJson(LSHandle *sh, jvalue_ref *ret_obj, LSError *lserror)
{
    _Catalog *catalog = sh->catalog;
    const char *key = NULL;
    _SubList *sub_list = NULL;
    GHashTableIter iter;

    jvalue_ref true_obj = NULL;
    jvalue_ref array = NULL;
    jvalue_ref cur_obj = NULL;
    jvalue_ref sub_array = NULL;
    jvalue_ref key_name = NULL;
    jvalue_ref message_obj = NULL;
    jvalue_ref sub_array_item = NULL;
    jvalue_ref unique_name_obj = NULL;
    jvalue_ref service_name_obj = NULL;

    *ret_obj = jobject_create();
    if (*ret_obj == NULL) goto error;

    true_obj = jboolean_create(true);
    if (true_obj == NULL) goto error;

    array = jarray_create(NULL);
    if (array == NULL) goto error;

    /* returnValue: true,
     * subscriptions: [
     *  { key: key_name, subscribers: [{unique_name: , service_name: }, ...] },
     *  ...
     * ]
     */
    _CatalogLock(catalog);

    g_hash_table_iter_init(&iter, catalog->subscription_lists);

    while (g_hash_table_iter_next(&iter, (gpointer)&key, (gpointer)&sub_list))
    {
        cur_obj = jobject_create();
        if (cur_obj == NULL) goto error;

        sub_array = jarray_create(NULL);
        if (sub_array == NULL) goto error;

        key_name = jstring_create_copy(j_cstr_to_buffer(key));
        if (key_name == NULL) goto error;

        /* iterate over SubList */
        int i = 0;
        const char *token = NULL;
        const int len = _SubListLen(sub_list);
        for (i = 0; i < len; i++)
        {
            token = _SubListGet(sub_list, i);

            if (token)
            {
                _Subscription *sub = g_hash_table_lookup(catalog->token_map, token);

                if (!sub) continue;

                LSMessage *msg = sub->message;
                const char *unique_name = LSMessageGetSender(msg);
                const char *service_name = LSMessageGetSenderServiceName(msg);
                const char *message_body = LSMessageGetPayload(msg);

                /* create subscribers item and add to sub_array */
                sub_array_item = jobject_create();
                if (sub_array_item == NULL) goto error;

                unique_name_obj = unique_name ? jstring_create_copy(j_cstr_to_buffer(unique_name))
                                  : jstring_empty();
                if (unique_name_obj == NULL) goto error;

                service_name_obj = service_name ? jstring_create_copy(j_cstr_to_buffer(service_name))
                                   : jstring_empty();
                if (service_name_obj == NULL) goto error;

                message_obj = message_body ? jstring_create_copy(j_cstr_to_buffer(message_body))
                              : jstring_empty();
                if (message_obj == NULL) goto error;

                jobject_put(sub_array_item,
                            J_CSTR_TO_JVAL("unique_name"),
                            unique_name_obj);
                jobject_put(sub_array_item,
                            J_CSTR_TO_JVAL("service_name"),
                            service_name_obj);
                jobject_put(sub_array_item,
                            J_CSTR_TO_JVAL("subscription_message"),
                            message_obj);
                jarray_append(sub_array, sub_array_item);

                sub_array_item = NULL;
                unique_name_obj = NULL;
                service_name_obj = NULL;
                message_obj = NULL;
            }
        }
        jobject_put(cur_obj, J_CSTR_TO_JVAL("key"),
                    key_name);
        jobject_put(cur_obj,
                    J_CSTR_TO_JVAL("subscribers"),
                    sub_array);
        jarray_append(array, cur_obj);
        key_name = NULL;
        cur_obj = NULL;
        sub_array = NULL;
    }

    jobject_put(*ret_obj,
                J_CSTR_TO_JVAL("returnValue"),
                true_obj);
    jobject_put(*ret_obj,
                J_CSTR_TO_JVAL("subscriptions"), array);

    _CatalogUnlock(catalog);

    return true;

error:
    _CatalogUnlock(catalog);

    j_release(ret_obj);
    j_release(&true_obj);
    j_release(&array);

    j_release(&cur_obj);
    j_release(&sub_array);
    j_release(&key_name);

    j_release(&sub_array_item);
    j_release(&unique_name_obj);
    j_release(&service_name_obj);

    return false;
}
Exemplo n.º 7
0
static bool
_CatalogAdd(_Catalog *catalog, const char *key,
            LSMessage *message, LSError *lserror)
{
    bool retVal = false;
    const char *token = LSMessageGetUniqueToken(message);
    if (!token)
    {
        _LSErrorSet(lserror, MSGID_LS_TOKEN_ERR, -1, "Could not get unique token");
        return false;
    }

    _CatalogLock(catalog);

    _SubList *list =
        g_hash_table_lookup(catalog->subscription_lists, key);
    if (!list)
    {
        list = _SubListNew();
        g_hash_table_replace(catalog->subscription_lists,
                             g_strdup(key), list);
    }

    const char* client_name = LSMessageGetSender(message);
    if (!client_name)
    {
        _LSErrorSet(lserror, MSGID_LS_UNAME_ERR, -1, "Could not get service unique name");
        return false;
    }

    _SubList *client_list =
        g_hash_table_lookup(catalog->client_subscriptions, client_name);
    if (!client_list)
    {
        client_list = _SubListNew();
        g_hash_table_replace(catalog->client_subscriptions,
                             g_strdup(client_name), client_list);
    }

    _Subscription *subs = g_hash_table_lookup(catalog->token_map, token);
    if (!subs)
    {
        subs = _SubscriptionNew(catalog->sh, message);
        if (subs)
        {
            g_hash_table_replace(catalog->token_map, g_strdup(token), subs);
        }
        else
        {
            goto cleanup;
        }
    }
    LS_ASSERT(subs->message == message);

    if (!_SubListContains(list, token))
    {
        _SubListAdd(list, g_strdup(token));
    }

    if (!_SubListContains(client_list, token))
    {
        _SubListAdd(client_list, g_strdup(token));
    }

    if (!g_char_ptr_array_contains(subs->keys, key))
    {
        g_ptr_array_add(subs->keys, g_strdup(key));
    }

    retVal = true;

cleanup:
    _CatalogUnlock(catalog);
    return retVal;
}