void
_LSTransportClientUnref(_LSTransportClient *client)
{
    calls_to_clientunref++;
    client->ref--;

    g_assert_cmpint(client->ref, >=, 0);
    if(client->ref == 0)
    {
        if(client->incoming)
        {
            while (!g_queue_is_empty(client->incoming->complete_messages))
            {
                _LSTransportMessage *message = g_queue_pop_head(client->incoming->complete_messages);
                _LSTransportMessageUnref(message);
            }
            g_queue_free(client->incoming->complete_messages);
            g_slice_free(_LSTransportIncoming, client->incoming);
        }
        if(client->outgoing)
        {
            while (!g_queue_is_empty(client->outgoing->queue))
            {
                _LSTransportMessage *message = g_queue_pop_head(client->outgoing->queue);
                _LSTransportMessageUnref(message);
            }
            g_queue_free(client->outgoing->queue);
            g_slice_free(_LSTransportOutgoing, client->outgoing);
        }
        g_slice_free(_LSTransportClient, client);
    }
}
static void
test_LSTransportIncoming_execute(int number_of_messages)
{
    _LSTransportIncoming *inqueue = _LSTransportIncomingNew();

    /* Is incoming message queue constructed? */
    g_assert(NULL != inqueue);
    g_assert(NULL != inqueue->complete_messages);

    /* The mutex should be initialized. */
    g_assert_cmpint(pthread_mutex_trylock(&inqueue->lock), !=, EINVAL);
    pthread_mutex_unlock(&inqueue->lock);

    _LSTransportMessage *messages[number_of_messages];
    int i;

    /* Fill queue with (possible) test data. */
    for(i = 0; i < number_of_messages; i++)
    {
        _LSTransportMessage *message = _LSTransportMessageNewRef(LS_TRANSPORT_MESSAGE_DEFAULT_PAYLOAD_SIZE);
        /* Increment ref count (possible to check message ref count after _LSTransportIncomingFree) */
        _LSTransportMessageRef(message);
        g_assert_cmpint(message->ref, ==, 2);
        messages[i] = message;

        g_queue_push_head(inqueue->complete_messages, message);
    }

    /* Simulate the message are processed */
    while (!g_queue_is_empty(inqueue->complete_messages))
    {
        _LSTransportMessage *message = g_queue_pop_head(inqueue->complete_messages);
        _LSTransportMessageUnref(message);
    }

    /* Free the struct. */
    _LSTransportIncomingFree(inqueue);

    /* The mutex should be destroyed. */
    g_assert_cmpint(pthread_mutex_trylock(&inqueue->lock), ==, EINVAL);

    /* See if the messages in the queue were unreferenced. */
    for(i = 0; i < number_of_messages; i++)
    {
        g_assert_cmpint(messages[i]->ref, ==, 1);
    }

    /* Cleanup. All testing is now over. */
    for(i = 0; i < number_of_messages; i++)
    {
        _LSTransportMessageUnref(messages[i]);
    }
}
/**
 *******************************************************************************
 * @brief Send a signal registration message.
 *
 * @param  transport    IN  transport
 * @param  reg          IN  true to register, false to unregister
 * @param  category     IN  category (required)
 * @param  method       IN  method (optional, NULL means none)
 * @param  token        OUT message token
 * @param  lserror      OUT set on error
 *
 * @retval  true on success
 * @retval  false on failure
 *******************************************************************************
 */
bool
_LSTransportSignalRegistration(_LSTransport *transport, bool reg, const char *category,
                               const char *method, LSMessageToken *token, LSError *lserror)
{
    /*
     * format:
     *
     * category + NUL
     * method + NUL (if method is NULL, then we just have NUL)
     */
    bool ret = true;
    int category_len = strlen_safe(category) + 1;
    int method_len = strlen_safe(method) + 1;

    LOG_LS_TRACE("%s: category: %s, method: %s\n", __func__, category, method);

    _LSTransportMessage *message = _LSTransportMessageNewRef(category_len + method_len);

    if (reg)
    {
        _LSTransportMessageSetType(message, _LSTransportMessageTypeSignalRegister);
    }
    else
    {
        _LSTransportMessageSetType(message, _LSTransportMessageTypeSignalUnregister);
    }

    char *message_body = _LSTransportMessageGetBody(message);

    LS_ASSERT(message_body != NULL);

    memcpy(message_body, category, category_len);
    message_body += category_len;

    if (method_len == 1)
    {
        char nul = '\0';
        memcpy(message_body, &nul, sizeof(nul));
    }
    else
    {
        memcpy(message_body, method, method_len);
    }

    LS_ASSERT(transport->hub != NULL);

    if (!_LSTransportSendMessage(message, transport->hub, token, lserror))
    {
        ret = false;
    }

    _LSTransportMessageUnref(message);

    return ret;
}
/**
 *******************************************************************************
 * @brief Free a serial list item.
 *
 * @param  list_item    IN serial list item to free
 *******************************************************************************
 */
void
_LSTransportSerialListItemFree(_LSTransportSerialListItem *list_item)
{
    LS_ASSERT(list_item != NULL);

    _LSTransportMessageUnref(list_item->message);

#ifdef MEMCHECK
    memset(list_item, 0xFF, sizeof(_LSTransportSerialListItem));
#endif

    g_slice_free(_LSTransportSerialListItem, list_item);
}
/**
 *******************************************************************************
 * @brief Send a signal.
 *
 * @param  transport    IN  transport
 * @param  category     IN  category
 * @param  method       IN  method (optional, NULL means none)
 * @param  payload      IN  payload
 * @param  lserror      OUT set on error
 *
 * @retval  true on success
 * @retval  false on failure
 *******************************************************************************
 */
bool
LSTransportSendSignal(_LSTransport *transport, const char *category, const char *method, const char *payload, LSError *lserror)
{
    bool ret = true;

    _LSTransportMessage *message = LSTransportMessageSignalNewRef(category, method, payload);

    LS_ASSERT(transport->hub != NULL);

    ret = _LSTransportSendMessage(message, transport->hub, NULL, lserror);

    _LSTransportMessageUnref(message);

    return ret;
}
Beispiel #6
0
_LSTransportMessage*
LSCustomMessageQueuePop(LSCustomMessageQueue *q)
{
    /* lock queue */
    pthread_mutex_lock(&q->lock);

    _LSTransportMessage *ret = g_queue_pop_head(q->queue);
    
    /* unlock queue */
    pthread_mutex_unlock(&q->lock);
    
    if (ret) _LSTransportMessageUnref(ret);

    return ret;
}
void
_LSMessageFree(LSMessage *message)
{
    if (message->transport_msg)
        _LSTransportMessageUnref(message->transport_msg);

    g_free(message->uniqueTokenAllocated);
    g_free(message->kindAllocated);

    g_free(message->methodAllocated);
    g_free(message->payloadAllocated);

#ifdef MEMCHECK
    memset(message, 0xFF, sizeof(LSMessage));
#endif

    g_free(message);
}
Beispiel #8
0
void
LSCustomMessageQueueFree(LSCustomMessageQueue *q)
{
    /* clean up any remaining messages on the queue */
    while (!g_queue_is_empty(q->queue))
    {
        _LSTransportMessage *message = g_queue_pop_head(q->queue);
        _LSTransportMessageUnref(message);
    }

    g_queue_free(q->queue);

#ifdef MEMCHECK
    memset(q, 0xFF, sizeof(LSCustomMessageQueue));
#endif

    g_free(q);
}
/**
 *******************************************************************************
 * @brief Free an outgoing queue.
 *
 * @param  outgoing     IN  outgoing queue
 *******************************************************************************
 */
void
_LSTransportOutgoingFree(_LSTransportOutgoing *outgoing)
{
    LS_ASSERT(outgoing != NULL);
    LS_ASSERT(outgoing->queue != NULL);
    LS_ASSERT(outgoing->serial != NULL);

    while (!g_queue_is_empty(outgoing->queue))
    {
        _LSTransportMessage *message = g_queue_pop_head(outgoing->queue);
        _LSTransportMessageUnref(message);
    }
    g_queue_free(outgoing->queue);

    _LSTransportSerialFree(outgoing->serial);

#ifdef MEMCHECK
    memset(outgoing, 0xFF, sizeof(_LSTransportOutgoing));
#endif

    g_slice_free(_LSTransportOutgoing, outgoing);
}