*/
static int current_lifeness;
+/**
+ * Priority used currently in #GNUNET_SCHEDULER_do_work().
+ */
+static enum GNUNET_SCHEDULER_Priority work_priority;
+
/**
* Function to use as a select() in the scheduler.
* If NULL, we use GNUNET_NETWORK_socket_select().
unsigned int
GNUNET_SCHEDULER_get_load (enum GNUNET_SCHEDULER_Priority p)
{
- struct GNUNET_SCHEDULER_Task *pos;
unsigned int ret;
GNUNET_assert (NULL != active_task);
if (p == GNUNET_SCHEDULER_PRIORITY_KEEP)
p = current_priority;
ret = 0;
- for (pos = ready_head[check_priority (p)]; NULL != pos; pos = pos->next)
+ for (struct GNUNET_SCHEDULER_Task *pos = ready_head[check_priority (p)];
+ NULL != pos;
+ pos = pos->next)
ret++;
return ret;
}
struct GNUNET_SCHEDULER_Task *t;
struct GNUNET_SCHEDULER_Task *pos;
struct GNUNET_SCHEDULER_Task *prev;
+ struct GNUNET_TIME_Relative left;
/* scheduler must be running */
GNUNET_assert (NULL != scheduler_driver);
t->timeout = at;
t->priority = check_priority (priority);
t->lifeness = current_lifeness;
+ init_backtrace (t);
+
+ left = GNUNET_TIME_absolute_get_remaining (at);
+ if (0 == left.rel_value_us)
+ {
+ queue_ready_task (t);
+ if (priority > work_priority)
+ work_priority = priority;
+ return t;
+ }
+
/* try tail first (optimization in case we are
* appending to a long list of tasks with timeouts) */
if ((NULL == pending_timeout_head) ||
}
/* finally, update heuristic insertion point to last insertion... */
pending_timeout_last = t;
-
LOG (GNUNET_ERROR_TYPE_DEBUG,
"Adding task %p\n",
t);
- init_backtrace (t);
return t;
}
int
GNUNET_SCHEDULER_do_work (struct GNUNET_SCHEDULER_Handle *sh)
{
- enum GNUNET_SCHEDULER_Priority p;
struct GNUNET_SCHEDULER_Task *pos;
struct GNUNET_TIME_Absolute now;
GNUNET_assert (NULL == ready_head[GNUNET_SCHEDULER_PRIORITY_KEEP]);
/* yes, p>0 is correct, 0 is "KEEP" which should
* always be an empty queue (see assertion)! */
- for (p = GNUNET_SCHEDULER_PRIORITY_COUNT - 1; p > 0; p--)
+ for (work_priority = GNUNET_SCHEDULER_PRIORITY_COUNT - 1;
+ work_priority > 0;
+ work_priority--)
{
- pos = ready_head[p];
+ pos = ready_head[work_priority];
if (NULL != pos)
break;
}
GNUNET_assert (NULL != pos); /* ready_count wrong? */
/* process all tasks at this priority level, then yield */
- while (NULL != (pos = ready_head[p]))
+ while (NULL != (pos = ready_head[work_priority]))
{
- GNUNET_CONTAINER_DLL_remove (ready_head[p],
- ready_tail[p],
+ GNUNET_CONTAINER_DLL_remove (ready_head[work_priority],
+ ready_tail[work_priority],
pos);
ready_count--;
current_priority = pos->priority;
/* Setup initial tasks */
current_priority = GNUNET_SCHEDULER_PRIORITY_DEFAULT;
current_lifeness = GNUNET_NO;
+ /* ensure this task runs first, by using a priority level reserved for
+ the scheduler (not really shutdown, but start-up ;-) */
install_parent_control_task =
- GNUNET_SCHEDULER_add_now (&install_parent_control_handler,
- NULL);
+ GNUNET_SCHEDULER_add_with_priority (GNUNET_SCHEDULER_PRIORITY_SHUTDOWN,
+ &install_parent_control_handler,
+ NULL);
shutdown_pipe_task =
GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
pr,
LOG (GNUNET_ERROR_TYPE_DEBUG,
"service: sending message with type %u\n",
ntohs (client->msg->type));
-
-
client->send_task = NULL;
buf = (const char *) client->msg;
left = ntohs (client->msg->size) - client->msg_pos;
- ret = GNUNET_NETWORK_socket_send (client->sock, &buf[client->msg_pos], left);
+ ret = GNUNET_NETWORK_socket_send (client->sock,
+ &buf[client->msg_pos],
+ left);
GNUNET_assert (ret <= (ssize_t) left);
if (0 == ret)
{
ntohs (msg->size));
client->msg = msg;
client->msg_pos = 0;
- client->send_task =
- GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
- client->sock,
- &do_send,
- client);
+ client->send_task = GNUNET_SCHEDULER_add_now (&do_send,
+ client);
}