Exemple #1
0
/**
 * timerqueue_getptr(Q, tv):
 * If the least timeval in ${Q} is less than or equal to ${tv}, return the
 * associated pointer and remove the pair from the priority queue.  If not,
 * return NULL.
 */
void *
timerqueue_getptr(struct timerqueue * Q, const struct timeval * tv)
{
	struct timerrec * r;
	void * ptr;

	/*
	 * Get the minimum element from the heap.  Return NULL if the heap
	 * has no minimum element (i.e., is empty).
	 */
	if ((r = ptrheap_getmin(Q->H)) == NULL)
		return (NULL);

	/* If the minimum timeval is greater than ${tv}, return NULL. */
	if (tvcmp(&r->tv, tv) > 0)
		return (NULL);

	/* Remove this record from the heap. */
	ptrheap_deletemin(Q->H);

	/* Extract its pointer. */
	ptr = r->ptr;

	/* Free the record. */
	free(r);

	/*
	 * And finally return the pointer which was associated with the
	 * (formerly) minimum timeval in the heap.
	 */
	return (ptr);
}
Exemple #2
0
/**
 * timerqueue_free(Q):
 * Free the timer priority queue ${Q}.
 */
void
timerqueue_free(struct timerqueue * Q)
{
	struct timerrec * r;

	/* Behave consistently with free(NULL). */
	if (Q == NULL)
		return;

	/* Extract elements from the heap and free them one by one. */
	while ((r = ptrheap_getmin(Q->H)) != NULL) {
		free(r);
		ptrheap_deletemin(Q->H);
	}

	/* Free the heap. */
	ptrheap_free(Q->H);

	/* Free the timer priority queue structure. */
	free(Q);
}
Exemple #3
0
/**
 * storage_findfiles(path):
 * Look for files named "blks_<16 hex digits>" in the directory ${path}.
 * Return an elastic queue of struct storage_file, in order of increasing
 * fileno.
 */
struct elasticqueue *
storage_findfiles(const char * path)
{
	struct stat sb;
	DIR * dir;
	struct dirent * dp;
	struct ptrheap * H;
	struct storage_file * sf;
	char * s;
	uint8_t fileno_exp[8];
	struct elasticqueue * Q;

	/* Create a heap for holding storage_file structures. */
	if ((H = ptrheap_init(fs_compar, NULL, NULL)) == NULL)
		goto err0;

	/* Create a queue for holding the structures in sorted order. */
	if ((Q = elasticqueue_init(sizeof(struct storage_file))) == NULL)
		goto err1;

	/* Open the storage directory. */
	if ((dir = opendir(path)) == NULL) {
		warnp("Cannot open storage directory: %s", path);
		goto err2;
	}

	/*
	 * Look for files named "blks_<64-bit hexified first block #>" and
	 * create storage_file structures for each.
	 */
	while ((errno = 0), ((dp = readdir(dir)) != NULL)) {
		/* Skip anything which isn't the right length. */
		if (strlen(dp->d_name) != strlen("blks_0123456789abcdef"))
			continue;

		/* Skip anything which doesn't start with "blks_". */
		if (strncmp(dp->d_name, "blks_", 5))
			continue;

		/* Make sure the name has 8 hexified bytes and parse. */
		if (unhexify(&dp->d_name[5], fileno_exp, 8))
			continue;

		/* Construct a full path to the file and stat. */
		if (asprintf(&s, "%s/%s", path, dp->d_name) == -1) {
			warnp("asprintf");
			goto err3;
		}
		if (lstat(s, &sb)) {
			warnp("stat(%s)", s);
			goto err4;
		}

		/* Skip anything other than regular files. */
		if (!S_ISREG(sb.st_mode))
			goto next;

		/* Allocate a file_state structure. */
		if ((sf = malloc(sizeof(struct storage_file))) == NULL)
			goto err4;

		/* Fill in file number and size. */
		sf->fileno = be64dec(fileno_exp);
		sf->len = sb.st_size;

		/* Insert the file into the heap. */
		if (ptrheap_add(H, sf))
			goto err5;

next:
		/* Free the full path to the file. */
		free(s);
	}
	if (errno != 0) {
		warnp("Error reading storage directory: %s", path);
		goto err3;
	}

	/* Close the storage directory. */
	while (closedir(dir)) {
		/* Retry if we were interrupted. */
		if (errno == EINTR)
			continue;

		/* Oops, something bad happened. */
		warnp("Error closing storage directory: %s", path);
		goto err2;
	}

	/* Suck structures from the heap into the queue. */
	while ((sf = ptrheap_getmin(H)) != NULL) {
		if (elasticqueue_add(Q, sf))
			goto err2;
		free(sf);
		ptrheap_deletemin(H);
	}

	/* Free the (now empty) heap. */
	ptrheap_free(H);

	/* Success! */
	return (Q);

err5:
	free(sf);
err4:
	free(s);
err3:
	closedir(dir);
err2:
	elasticqueue_free(Q);
err1:
	while ((sf = ptrheap_getmin(H)) != NULL) {
		ptrheap_deletemin(H);
		free(sf);
	}
	ptrheap_free(H);
err0:
	/* Failure! */
	return (NULL);
}