/* * 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 #include #include #include #if defined(__APPLE__) #include #endif #include #include #if defined(DMALLOC) #include #include #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; }