Example #1
0
int ListMutableIteratorAppend(ListMutableIterator *iterator, void *payload)
{
    if (!iterator)
        return -1;
    if (IsMutableIteratorValid(iterator))
        return -1;
    ListNode *node = NULL;
    node = (ListNode *)malloc(sizeof(ListNode));
    if (!node) {
        // This is unlikely in Linux but other Unixes actually return NULL
        return -1;
    }
    ListDetach(iterator->origin);
    node->next = NULL;
    node->payload = payload;
    if (iterator->current->next) {
        node->next = iterator->current->next;
        node->previous = iterator->current;
        iterator->current->next->previous = node;
        iterator->current->next = node;
    } else {
        // Last element
        node->next = NULL;
        node->previous = iterator->current;
        iterator->current->next = node;
        iterator->origin->last = node;
    }
    iterator->origin->node_count++;
    return 0;
}
Example #2
0
int ListAppend(List *list, void *payload)
{
    ListNode *node = NULL;
    if (!list)
    {
        return -1;
    }
    ListDetach(list);
    node = (ListNode *)malloc(sizeof(ListNode));
    if (!node)
    {
        // This is unlikely in Linux but other Unixes actually return NULL
        return -1;
    }
    node->next = NULL;
    node->payload = payload;
    if (list->last)
    {
        // We have elements
        node->previous = list->last;
        list->last->next = node;
    }
    else
    {
        // First element
        node->previous = NULL;
        list->list = node;
        list->first = node;
    }
    list->last = node;
    list->node_count++;
    return 0;
}
Example #3
0
int ListMutableIteratorPrepend(ListMutableIterator *iterator, void *payload)
{
    if (!iterator)
        return -1;
    if (IsMutableIteratorValid(iterator))
        return -1;
    ListNode *node = NULL;
    node = (ListNode *)malloc(sizeof(ListNode));
    if (!node) {
        return -1;
    }
    ListDetach(iterator->origin);
    node->payload = payload;
    if (iterator->current->previous) {
        node->previous = iterator->current->previous;
        node->next = iterator->current;
        iterator->current->previous->next = node;
        iterator->current->previous = node;
    } else {
        // First element
        node->previous = NULL;
        node->next = iterator->current;
        iterator->current->previous = node;
        iterator->origin->first = node;
        iterator->origin->list = node;
    }
    iterator->origin->node_count++;
    return 0;
}
Example #4
0
int ListPrepend(List *list, void *payload)
{
    ListNode *node = NULL;
    if (!list)
    {
        return -1;
    }
    ListDetach(list);
    node = (ListNode *)malloc(sizeof(ListNode));
    node->payload = payload;
    node->previous = NULL;
    if (list->list)
    {
        // We have elements
        node->next = list->list;
        list->list->previous = node;
    }
    else
    {
        // First element
        node->next = NULL;
        list->last = node;
    }
    list->list = node;
    list->first = node;
    list->node_count++;
    return 0;
}
Example #5
0
int ListRemove(List *list, void *payload)
{
    if (!list || !payload)
        return -1;
    ListNode *node = NULL;
    /*
     * This is a complicated matter. We could detach the list before
     * we know that we have a new node, but that will mean that we
     * might have copied the whole list without real reasons. On the
     * other hand, it saves us a whole traversal of the list if we
     * just do it.
     */
    int found = ListFindNode(list, payload);
    if (!found)
        return -1;
    ListDetach(list);
    node = NULL;
    /*
     * We need to find the node again since we have a new list.
     * In theory we don't have to worry about the existence of the node,
     * since the list has not changed, it might have been copied but
     * it is still the same as before.
     */
    for (node = list->list; node; node = node->next) 
	{
        if (list->compare) 
		{
            if (!list->compare(node->payload, payload)) 
			{
                found = 1;
                break;
            }
        } 
		else 
		{
            if (node->payload == payload) 
			{
                found = 1;
                break;
            }
        }
    }
    /*
     * Before deleting the node we have to update the mutable iterator.
     * We might need to advance it!
     */
    ListUpdateMutableIterator(list, node);
    ListRemoveNode(list, node);
    if (list->destroy && node->payload) 
    {
        list->destroy(node->payload);
	}
    free(node);
    ListUpdateListState(list);
    return 0;
}
Example #6
0
char* SocketBuffer_complete(int socket)
{
    FUNC_ENTRY;
    if (ListFindItem(queues, &socket, socketcompare))
    {
        socket_queue* queue = (socket_queue*)(queues->current->content);
        SocketBuffer_freeDefQ();
        def_queue = queue;
        ListDetach(queues, queue);
    }
    def_queue->socket = def_queue->index = def_queue->headerlen = def_queue->datalen = 0;
    FUNC_EXIT;
    return def_queue->buf;
}
Example #7
0
static PyObject* mqttv3_setcallbacks(PyObject* self, PyObject *args)
{
	MQTTClient c;
	CallbackEntry* e = NULL;
	int rc;

	e = malloc(sizeof(CallbackEntry));

	if (!PyArg_ParseTuple(args, "kOOOO", &c, (PyObject**) &e->context, &e->cl,
			&e->ma, &e->dc))
		return NULL;
	e->c = c;

	printf("setCallbacks MQTTClient pointer %p\n", c);

	if ((e->cl != Py_None && !PyCallable_Check(e->cl))
			|| (e->ma != Py_None && !PyCallable_Check(e->ma))
			|| (e->dc != Py_None && !PyCallable_Check(e->dc)))
	{
		PyErr_SetString(PyExc_TypeError,
				"3rd, 4th and 5th parameters must be callable or None");
		return NULL;
	}

	Py_BEGIN_ALLOW_THREADS rc = MQTTClient_setCallbacks(c, e, connectionLost,
			messageArrived, deliveryComplete);
	Py_END_ALLOW_THREADS

	if (rc == MQTTCLIENT_SUCCESS)
	{
		ListElement* temp = NULL;
		if ((temp = ListFindItem(callbacks, c, clientCompare)) != NULL)
		{
			ListDetach(callbacks, temp->content);
			free(temp->content);
		}
		ListAppend(callbacks, e, sizeof(e));
		Py_XINCREF(e->cl);
		Py_XINCREF(e->ma);
		Py_XINCREF(e->dc);
		Py_XINCREF(e->context);
	}

	return Py_BuildValue("i", rc);
}
Example #8
0
static PyObject* mqttv3_destroy(PyObject* self, PyObject *args)
{
	MQTTClient c;
	ListElement* temp = NULL;

	if (!PyArg_ParseTuple(args, "k", &c))
		return NULL;

	if ((temp = ListFindItem(callbacks, c, clientCompare)) != NULL)
	{
		ListDetach(callbacks, temp->content);
		free(temp->content);
	}

	MQTTClient_destroy(&c);

	Py_INCREF(Py_None);
	return Py_None;
}
Example #9
0
int ListMutableIteratorRemove(ListMutableIterator *iterator)
{
    if (!iterator)
        return -1;
    if (IsMutableIteratorValid(iterator))
        return -1;
    ListDetach(iterator->origin);
    /*
     * Removing an element is not as simple as it sounds. We need to inform the list
     * and make sure we move out of the way.
     */
    ListNode *node = NULL;
    if (iterator->current->next) {
        /*
         * We are not the last element, therefore we proceed as normal.
         */
        node = iterator->current->next;
    } else {
        /*
         * We might be the last element or the only element on the list.
         * If we are the only element we do not destroy the element otherwise the iterator
         * would become invalid.
         */
        if (iterator->current->previous) {
            /*
             * last element
             */
            node = iterator->current->previous;
        } else
            return -1;
    }
    ListRemoveNode(iterator->origin, iterator->current);
    if (iterator->origin->destroy)
        iterator->origin->destroy(iterator->current->payload);
    free (iterator->current);
    iterator->current = node;
    ListUpdateListState(iterator->origin);
    return 0;
}
Example #10
0
/**
 * Start the publish exchange for any queued messages, if possible.
 * When the inflight message queue is not at maximum capacity we can start a new
 * publication.
 * @param client the client to process queued messages for
 */
int MQTTProtocol_processQueued(Clients* client)
{
	int rc = 0;
#if defined(QOS0_SEND_LIMIT)
	int qos0count = 0;
#endif
	int threshold_log_message_issued = 0;

	FUNC_ENTRY;
	if (Protocol_isClientQuiescing(client))
		goto exit; /* don't create new work - just finish in-flight stuff */


	Log(TRACE_MAXIMUM, 0, NULL, client->clientID);
	while (client->good && Socket_noPendingWrites(client->socket) && /* no point in starting a publish if a write is still pending */
		client->outboundMsgs->count < bstate->max_inflight_messages &&
		queuedMsgsCount(client) > 0
#if defined(QOS0_SEND_LIMIT)
		&& qos0count < bstate->max_inflight_messages /* an arbitrary criterion - but when would we restart? */
#endif
		#if defined(MQTTS)
		&& (client->protocol == PROTOCOL_MQTT || client->outboundMsgs->count == 0)
#endif
		)
	{
		int pubrc = TCPSOCKET_COMPLETE;
		Messages* m = NULL;
		int threshold = (THRESHOLD * bstate->max_queued_messages) / 100;
		List* queue = NULL;
		int i;

		for (i = PRIORITY_MAX-1; i >= 0; --i)
		{
			if (client->queuedMsgs[i]->count > 0)
			{
				queue = client->queuedMsgs[i];
				break;
			}
		}
		m = (Messages*)(queue->first->content);

		Log(TRACE_MAXIMUM, 1, NULL, client->clientID);
#if defined(MQTTS)
		if (client->protocol == PROTOCOL_MQTTS && strlen(m->publish->topic) > 2 &&
				MQTTSProtocol_getRegisteredTopicId(client, m->publish->topic) == 0)
		{
			if (client->pendingRegistration == NULL)
				rc = MQTTSProtocol_startRegistration(client, m->publish->topic);
				goto exit;
		}

#endif
#if defined(QOS0_SEND_LIMIT)
		if (m->qos == 0)
			++qos0count;
#endif

		pubrc = MQTTProtocol_startQueuedPublish(client, m);
		/* regardless of whether the publish packet was sent on the wire (pubrc is good), the
		 * message has been put onto the outbound queue, so it must be removed from
		 * the queuedMsgs queue
		 */
		if (pubrc != TCPSOCKET_COMPLETE && pubrc != TCPSOCKET_INTERRUPTED)
			client->good = 0;
		if (m->qos == 0)
		{
			/* This is done primarily for MQTT-S.
			 * A qos-0 message will be on this queue if its topic
			 * has to be registered first. Now that the message
			 * has been sent, it needs to be cleaned up as there
			 * won't be an ack to trigger it.
			 *
			 * For MQTT, there is a scenario in which qos-0 messages
			 * could be on this list for which the same applies.
			 *
			 * Note (IGC): this is also a bug fix I just implemented - applies equally to MQTTs and MQTT!
			 */
			MQTTProtocol_removePublication(m->publish);
			if (!ListRemove(queue, m))
				Log(LOG_ERROR, 38, NULL);
		}
		else if (!ListDetach(queue, m))
			Log(LOG_ERROR, 38, NULL);
		if (queuedMsgsCount(client) == threshold - 1 && !threshold_log_message_issued)
		{
			Log(LOG_INFO, 146, NULL, client->clientID, THRESHOLD);
			threshold_log_message_issued = 1;
		}
	}
#if defined(QOS0_SEND_LIMIT)
	if (qos0count >= bstate->max_inflight_messages)
		rc = 1;
#endif
exit:
	FUNC_EXIT_RC(rc);
	return rc;
}
Example #11
0
File: list.c Project: nperron/core
int ListRemove(List *list, void *payload)
{
    if (!list || !payload)
        return -1;
    ListNode *node = NULL;
    /*
     * This is a complicated matter. We could detach the list before
     * we know that we have a new node, but that will mean that we
     * might have copied the whole list without real reasons. On the
     * other hand, it saves us a whole traversal of the list if we
     * just do it.
     */
    int found = ListFindNode(list, payload);
    if (!found)
        return -1;
    found = 0;
    ListDetach(list);
    node = NULL;
    /*
     * We need to find the node again since we have a new list.
     * In theory we don't have to worry about the existence of the node,
     * since the list has not changed, it might have been copied but
     * it is still the same as before.
     */
    for (node = list->list; node; node = node->next) 
	{
        if (list->compare) 
		{
            if (!list->compare(node->payload, payload)) 
			{
                found = 1;
                break;
            }
        } 
		else 
		{
            if (node->payload == payload) 
			{
                found = 1;
                break;
            }
        }
    }
    /*
     * This is nearly impossible, so we will only assert it.
     */
    assert(found == 1);
    /*
     * Before deleting the node we have to update the mutable iterator.
     * We might need to advance it!
     */
    if (list->iterator)
    {
        if (list->iterator->current == node) 
        {
            /*
             * So lucky, it is the same node!
             * Move the iterator so it is not dangling.
             * Rules for moving:
             * 1. Move forward.
             * 2. if not possible, move backward.
             * 3. If not possible, then invalidate the iterator.
             */
            if (list->iterator->current->next)
            {
                list->iterator->current = list->iterator->current->next;
            }
            else if (list->iterator->current->previous)
            {
                list->iterator->current = list->iterator->current->previous;
            }
            else
            {
                list->iterator->valid = 0;
            }
        }
    }
    /*
     * Now, remove the node from the list and delete it.
     */
    if (node->next && node->previous) 
    {
        // Middle of the list
        node->next->previous = node->previous;
        node->previous->next = node->next;
    }
    else if (node->next)
    {
        // First element of the list
        list->list = node->next;
        list->first = node->next;
        node->next->previous = NULL;
    }
    else if (node->previous)
    {
        // Last element
        node->previous->next = NULL;
        list->last = node->previous;
    }
    else
    {
        // Single element
        list->list = NULL;
        list->first = NULL;
        list->last = NULL;
    }
    if (list->destroy && node->payload) 
    {
        list->destroy(node->payload);
    }
    else
    {
        free (node->payload);
    }
    free(node);
    ListUpdateListState(list);
    return 0;
}