Beispiel #1
0
axl_bool __turbulence_loop_read_first (TurbulenceLoop * loop)
{
	TurbulenceLoopDescriptor * loop_descriptor;

	loop_descriptor = vortex_async_queue_pop (loop->queue);

	/* check item received: if null received terminate loop */
	if (PTR_TO_INT (loop_descriptor) == -4)
		return axl_false;

	/* register loop_descriptor on the list */
	axl_list_append (loop->list, loop_descriptor);       

	return axl_true;
}
Beispiel #2
0
/** 
 * @brief Allows to get a list of connections registered on the
 * connection manager, matching the providing role and then filtered
 * by the provided filter string. 
 *
 * @param ctx The context where the operation will take place.
 *
 * @param role Connection role to select connections. Use -1 to select
 * all connections registered on the manager, no matter its role. 
 *
 * @param filter Optional filter expresion to resulting connection
 * list. It can be NULL.
 *
 * @return A newly allocated connection list having on each position a
 * reference to a MyQttConn object. The caller must finish the
 * list with axl_list_free to free resources. The function returns NULL if it fails.
 */
axlList *  myqttd_conn_mgr_conn_list   (MyQttdCtx            * ctx, 
					MyQttPeerRole          role,
					const char           * filter)
{
	axlList                * result;
	MyQttConn       * conn;
	axlHashCursor          * cursor;
	MyQttdConnMgrState * state;

	v_return_val_if_fail (ctx, NULL);

	/* lock and send */
	myqtt_mutex_lock (&ctx->conn_mgr_mutex);
	
	/* create the cursor */
	cursor = axl_hash_cursor_new (ctx->conn_mgr_hash);
	result = axl_list_new (axl_list_always_return_1, myqttd_conn_mgr_conn_list_free_item);

	msg ("connections registered: %d..", axl_hash_items (ctx->conn_mgr_hash));

	while (axl_hash_cursor_has_item (cursor)) {
		
		/* get data */
		state   = axl_hash_cursor_get_value (cursor);
		conn    = state->conn;

		/* check connection role to add it to the result
		   list */
		msg ("Checking connection role %d == %d", myqtt_conn_get_role (conn), role);
		if ((role == -1) || myqtt_conn_get_role (conn) == role) {
			/* update reference and add the connection */
			myqtt_conn_ref (conn, "conn-mgr-list");
			axl_list_append (result, conn);
		} /* end if */
		
		/* next cursor */
		axl_hash_cursor_next (cursor);
	}

	/* unlock */
	myqtt_mutex_unlock (&ctx->conn_mgr_mutex);

	/* free cursor */
	axl_hash_cursor_free (cursor);

	/* return list */
	return result;
}
Beispiel #3
0
axl_bool __turbulence_loop_read_pending (TurbulenceLoop * loop)
{
	TurbulenceLoopDescriptor * loop_descriptor, * aux;

	while (axl_true) {
		/* check if there are no pending items */
		if (vortex_async_queue_items (loop->queue) == 0)
			return axl_true;

		/* get descriptor */
		loop_descriptor = vortex_async_queue_pop (loop->queue);
			
		/* check item received: if null received terminate loop */
		if (PTR_TO_INT (loop_descriptor) == -4)
			return axl_false;

		/* support for removing loop descriptor */
		if (loop_descriptor->remove) {
			/* reset cursor to the first position */
			axl_list_cursor_first (loop->cursor);
			while (axl_list_cursor_has_item (loop->cursor)) {
				/* get current descriptor */
				aux = axl_list_cursor_get (loop->cursor);
				if (aux && aux->descriptor == loop_descriptor->descriptor) {
					/* element found, remove item */
					axl_list_cursor_remove (loop->cursor);
					break;
				} /* end if */

				/* next cursor */
				axl_list_cursor_next (loop->cursor);
			} /* end if */

			/* notify caller if he is waiting */
			if (loop_descriptor->queue_reply)
				vortex_async_queue_push (loop_descriptor->queue_reply, INT_TO_PTR (axl_true));

			axl_free (loop_descriptor);
			continue;
		} /* end if */

		/* register loop_descriptor on the list */
		axl_list_append (loop->list, loop_descriptor);       
	} /* end if */

	return axl_true;
}
Beispiel #4
0
/**
 * @brief Queues new data inside the given queue. 
 * 
 * push data at the queue's tail.
 *
 * @param queue the queue to use.
 * @param data user defined data to queue.
 * 
 * @return axl_true if the data was queue, axl_false if not
 **/
axl_bool           vortex_queue_push          (VortexQueue * queue, axlPointer data)
{

	/* check parameter */
	if (queue == NULL || data == NULL)
		return axl_false;

	vortex_mutex_lock   (&queue->mutex);

	/* place the data into the last position. The head queue is
	 * the first element to be poped, and the tail is where new
	 * data is placed. */
	axl_list_append (queue->queue, data);
	
	vortex_mutex_unlock (&queue->mutex);

	return axl_true;
}
enum jal_status jaln_process_init(VortexFrame *frame, struct jaln_init_info **info_out)
{
	if (!frame || !info_out || *info_out) {
		return JAL_E_INVAL;
	}
	enum jal_status ret = JAL_E_INVAL;

	struct jaln_init_info *info = jaln_init_info_create();

	if (!jaln_check_content_type_and_txfr_encoding_are_valid(frame)) {
		goto err_out;
	}

	const char *msg = VORTEX_FRAME_GET_MIME_HEADER(frame, JALN_HDRS_MESSAGE);
	if (!msg) {
		goto err_out;
	}

	if (0 != strcasecmp(msg, JALN_MSG_INIT)) {
		goto err_out;
	}

	const char *role = VORTEX_FRAME_GET_MIME_HEADER(frame, JALN_HDRS_MODE);
	if (!role) {
		goto err_out;
	}
	if (0 == strcasecmp(role, JALN_MSG_SUBSCRIBE_LIVE)) {
		info->role = JALN_ROLE_SUBSCRIBER;
		info->mode = JALN_LIVE_MODE;
	} else if (0 ==strcasecmp(role, JALN_MSG_SUBSCRIBE_ARCHIVE)) {
		info->role = JALN_ROLE_SUBSCRIBER;
		info->mode = JALN_ARCHIVE_MODE;
	} else if (0 == strcasecmp(role, JALN_MSG_PUBLISH_LIVE)) {
		info->role = JALN_ROLE_PUBLISHER;
		info->mode = JALN_LIVE_MODE;
	} else if (0 == strcasecmp(role, JALN_MSG_PUBLISH_ARCHIVE)) {
		info->role = JALN_ROLE_PUBLISHER;
		info->mode = JALN_ARCHIVE_MODE;
	} else {
		goto err_out;
	}
	const char *type = VORTEX_FRAME_GET_MIME_HEADER(frame, JALN_HDRS_DATA_CLASS);
	if (!type) {
		goto err_out;
	}
	if (0 == strcasecmp(type, JALN_STR_JOURNAL)) {
		info->type = JALN_RTYPE_JOURNAL;
	} else if (0 == strcasecmp(type, JALN_STR_AUDIT)) {
		info->type = JALN_RTYPE_AUDIT;
	} else if (0 == strcasecmp(type, JALN_STR_LOG)) {
		info->type = JALN_RTYPE_LOG;
	} else {
		goto err_out;
	}
	const char *agent = VORTEX_FRAME_GET_MIME_HEADER(frame, JALN_HDRS_AGENT);
	if (agent) {
		info->peer_agent = jal_strdup(agent);
	}
	char *cpy = NULL;
	const char *accept_dgst = VORTEX_FRAME_GET_MIME_HEADER(frame, JALN_HDRS_ACCEPT_DIGEST);
	if (accept_dgst) {
		cpy = jal_strdup(accept_dgst);
		char *cookie = NULL;
		char *token = NULL;
		for (token = strtok_r(cpy, ",", &cookie);
				token != NULL;
				token = strtok_r(NULL, ",", &cookie)) {
			axl_stream_trim(token);
			if (0 == strlen(token)) {
				goto err_out;
			}
			axl_list_append(info->digest_algs, jal_strdup(token));
		}
		free(cpy);
		cpy = NULL;
	} else {
		axl_list_append(info->digest_algs, jal_strdup(JALN_DGST_SHA256));
	}
	const char *accept_enc = VORTEX_FRAME_GET_MIME_HEADER(frame, JALN_HDRS_ACCEPT_ENCODING);
	if (accept_enc) {
		cpy = jal_strdup(accept_enc);
		char *cookie = NULL;
		char *token = NULL;
		for (token = strtok_r(cpy, ",", &cookie);
				token != NULL;
				token = strtok_r(NULL, ",", &cookie)) {
			axl_stream_trim(token);
			if (0 == strlen(token)) {
				goto err_out;
			}
			axl_list_append(info->encodings, jal_strdup(token));
		}
		free(cpy);
		cpy = NULL;
	} else {
		axl_list_append(info->encodings, jal_strdup(JALN_ENC_XML));
	}
	ret = JAL_OK;
	*info_out = info;
	goto out;
err_out:
	jaln_init_info_destroy(&info);
out:
	return ret;
}
Beispiel #6
0
/** 
 * @internal
 * 
 * This helper function dispatch the work to the right handler
 **/
axlPointer __valvula_thread_pool_dispatcher (ValvulaThreadPoolStarter * _data)
{
	/* get current context */
	ValvulaThreadPoolTask * task;
	ValvulaThread         * thread = _data->thread;
	ValvulaThreadPool     * pool   = _data->pool;
	ValvulaCtx            * ctx    = pool->ctx;
	ValvulaAsyncQueue     * queue  = _data->queue;

	/* local pointers to release soon data object */
	ValvulaThreadFunc       func;
	axlPointer             data;

	axl_free (_data);

	valvula_log (VALVULA_LEVEL_DEBUG, "thread from pool started");

	/* get a reference to the queue, waiting for the next work */
	while (axl_true) {

		/* get next task to process: precision=100ms */
		task = valvula_async_queue_timedpop (queue, 100000);
		
		if (task == NULL) {
			/* call to process events */
			__valvula_thread_pool_process_events (ctx, pool);

			/* do automatic reasize */
			__valvula_thread_pool_automatic_resize (ctx);

			continue;
		}

		if (PTR_TO_INT (task) == 3) {
			/* collect thread data terminated */
			valvula_mutex_lock (&(ctx->thread_pool->stopped_mutex));
			axl_list_remove_first (pool->stopped);
			valvula_mutex_unlock (&(ctx->thread_pool->stopped_mutex));
			continue;
		}

		/* check to stop current thread because pool was reduced */
		if (PTR_TO_INT (task) == 2) {
			valvula_log (VALVULA_LEVEL_DEBUG, "--> thread from pool stoping, found thread stop beacon");

			/* do not lock because this is already done by
			 * valvula_thread_pool_remove .. */
			valvula_mutex_lock (&(ctx->thread_pool->stopped_mutex));

			/* remove thread from the pool */
			valvula_mutex_lock (&pool->mutex);
			axl_list_unlink_ptr (pool->threads, thread);
			valvula_mutex_unlock (&pool->mutex);

			axl_list_append (pool->stopped, thread);
			valvula_mutex_unlock (&(ctx->thread_pool->stopped_mutex));

			valvula_async_queue_push (queue, INT_TO_PTR (3));

			/* unref the queue and return */
			valvula_async_queue_unref (queue);

			/* call to cleanup thread if defined */
			if (ctx->thread_pool_cleanup) 
				ctx->thread_pool_cleanup (ctx);

			/* unref ctx */
			valvula_ctx_unref2 (&ctx, "end pool dispatcher");
			return NULL;
		} /* end if */

		/* check stop in progress signal */
		if ((PTR_TO_INT (task) == 1) && ctx->thread_pool_being_stopped) {
			valvula_log (VALVULA_LEVEL_DEBUG, "--> thread from pool stoping, found finish beacon");

			/* unref the queue and return */
			valvula_async_queue_unref (queue);

			/* call to cleanup thread if defined */
			if (ctx->thread_pool_cleanup) 
				ctx->thread_pool_cleanup (ctx);
			
			valvula_ctx_unref2 (&ctx, "end pool dispatcher");

			return NULL;
		} /* end if */

		valvula_log (VALVULA_LEVEL_DEBUG, "--> thread from pool processing new job");

		/* grab references to release before call */
		func = task->func;
		data = task->data;
		axl_free (task);

		/* do automatic reasize (preemtive) */
		if (ctx && ctx->thread_pool && ctx->thread_pool->preemtive)
			__valvula_thread_pool_automatic_resize (ctx);

		/* at this point we already are executing inside a thread */
		if (! ctx->thread_pool_being_stopped && ! ctx->valvula_exit) 
			func (data);

		/* call to process events after finishing tasks */
		__valvula_thread_pool_process_events (ctx, pool);

		/* do automatic reasize */
		if (ctx && ctx->thread_pool && ! ctx->thread_pool->preemtive)
			__valvula_thread_pool_automatic_resize (ctx);

		valvula_log (VALVULA_LEVEL_DEBUG, "--> thread from pool waiting for jobs");

	} /* end if */
		
	/* That's all! */
	valvula_ctx_unref2 (&ctx, "end pool dispatcher");
	return NULL;
}