/*
* scamper_task.c
*
* $Id: scamper_task.c,v 1.17 2006/12/15 20:30:33 mjl Exp $
*
* Copyright (C) 2005-2006 The University of Waikato
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 2.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include <sys/time.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#if defined(__APPLE__)
#include <stdint.h>
#endif
#include <stdlib.h>
#include <assert.h>
#if defined(DMALLOC)
#include <string.h>
#include <dmalloc.h>
#endif
#include "scamper.h"
#include "scamper_addr.h"
#include "scamper_icmp_resp.h"
#include "scamper_task.h"
#include "scamper_queue.h"
#include "scamper_target.h"
#include "scamper_list.h"
#include "scamper_cyclemon.h"
#include "scamper_outfiles.h"
#include "scamper_addresslist.h"
#include "mjl_list.h"
#include "utils.h"
typedef struct task_onhold
{
void (*unhold)(void *param);
void *param;
} task_onhold_t;
void *scamper_task_onhold(scamper_task_t *task, void *param,
void (*unhold)(void *param))
{
task_onhold_t *toh;
dlist_node_t *cookie;
if(task->internal == NULL && (task->internal = dlist_alloc()) == NULL)
{
return NULL;
}
if((toh = malloc(sizeof(task_onhold_t))) == NULL)
{
return NULL;
}
if((cookie = dlist_tail_push(task->internal, toh)) == NULL)
{
free(toh);
return NULL;
}
toh->param = param;
toh->unhold = unhold;
return cookie;
}
int scamper_task_dehold(scamper_task_t *task, void *cookie)
{
task_onhold_t *toh;
assert(task->internal != NULL);
if((toh = dlist_node_pop(task->internal, cookie)) == NULL)
{
return -1;
}
free(toh);
return 0;
}
/*
* scamper_task_alloc
*
* allocate and initialise a task object.
*/
scamper_task_t *scamper_task_alloc(scamper_addr_t *addr,
scamper_task_funcs_t *funcs)
{
scamper_task_t *task;
if(addr == NULL) return NULL;
if(funcs == NULL) return NULL;
if((task = malloc_zero(sizeof(scamper_task_t))) != NULL)
{
task->dst = scamper_addr_use(addr);
task->funcs = funcs;
if(scamper_queue_alloc(task) == -1)
{
goto err;
}
}
return task;
err:
if(task->queue != NULL) scamper_queue_free(task->queue);
free(task);
return NULL;
}
/*
* scamper_task_free
*
* free a task that has been completed.
* this involves freeing the task using the free pointer provided,
* freeing the queue data structure, unholding any tasks blocked, and
* finally freeing the task structure itself.
*/
void scamper_task_free(scamper_task_t *task)
{
task_onhold_t *toh;
task->funcs->task_free(task);
scamper_queue_free(task->queue);
if(task->internal != NULL)
{
while((toh = dlist_head_pop(task->internal)) != NULL)
{
toh->unhold(toh->param);
free(toh);
}
dlist_free(task->internal);
}
if(task->dst != NULL) scamper_addr_free(task->dst);
if(task->cyclemon != NULL) scamper_cyclemon_unuse(task->cyclemon);
scamper_source_unuse(task->source);
free(task);
return;
}
syntax highlighted by Code2HTML, v. 0.9.1