completion.c 2.94 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
/*
 * (C) 2017 The University of Chicago
 * 
 * See COPYRIGHT in top-level directory.
 */

#include <stdlib.h>
#include "mobject-store-config.h"
#include "libmobject-store.h"
#include "completion.h"
#include "log.h"

int mobject_store_aio_create_completion(void *cb_arg,
                                mobject_store_callback_t cb_complete,
                                mobject_store_callback_t cb_safe,
                                mobject_store_completion_t *pc)
{
	int r;
	mobject_store_completion_t completion = 
		(mobject_store_completion_t)calloc(1, sizeof(struct mobject_store_completion));
	MOBJECT_ASSERT(completion != 0, "Could not allocate mobject_store_completion_t object"); 
	completion->cb_complete   = cb_complete;
	completion->cb_safe       = cb_safe;
	completion->cb_arg        = cb_arg;
	r = ABT_eventual_create(sizeof(int), (void**)(&(completion->eventual)));
	MOBJECT_ASSERT(r == ABT_SUCCESS, "Could not create ABT_eventual");
	completion->ret_value_ptr  = (int*)0;
	r = ABT_rwlock_create(&(completion->lock));
	MOBJECT_ASSERT(r == ABT_SUCCESS, "Could not create ABT_rwlock");

	*pc = completion;
	return 0;
}

int mobject_store_aio_wait_for_complete(mobject_store_completion_t c)
{
	int r;
	if(c == MOBJECT_COMPLETION_NULL) {
		MOBJECT_LOG("Warning: passing NULL to mobject_store_aio_wait_for_complete");
		return -1;
	}

	int* val_ptr = (int*)0;
	r = ABT_eventual_wait(c->eventual, (void**)(&val_ptr));
	MOBJECT_ASSERT(r == ABT_SUCCESS, "ABT_eventual_wait failed");
	r = ABT_rwlock_wrlock(c->lock);
	MOBJECT_ASSERT(r == ABT_SUCCESS, "ABT_rwlock_wrlock failed");
	c->ret_value_ptr = val_ptr;
	r = ABT_rwlock_unlock(c->lock);
	MOBJECT_ASSERT(r == ABT_SUCCESS, "ABT_rwlock_unlock failed");

	return 0;
}

int mobject_store_aio_is_complete(mobject_store_completion_t c)
{
	int r;
	if(c == MOBJECT_COMPLETION_NULL) {
		MOBJECT_LOG("Warning: passing NULL to mobject_store_aio_is_complete");
		return 0;
	}
	int result = 0;
	r = ABT_rwlock_rdlock(c->lock);
	MOBJECT_ASSERT(r == ABT_SUCCESS, "ABT_rwlock_rdlock failed");
	result = (c->ret_value_ptr != (int*)0);
	r = ABT_rwlock_unlock(c->lock);
	MOBJECT_ASSERT(r == ABT_SUCCESS, "ABT_rwlock_unlock failed");

	return result;
}

int mobject_store_aio_get_return_value(mobject_store_completion_t c)
{
	int r;
	if(c == MOBJECT_COMPLETION_NULL) {
		MOBJECT_LOG("Warning: passing NULL to mobject_store_aio_get_return_value");
		return 0;
	}
	int result = 0;
	r = ABT_rwlock_rdlock(c->lock);
	MOBJECT_ASSERT(r == ABT_SUCCESS, "ABT_rwlock_rdlock failed");
	if(c->ret_value_ptr != (int*)0) result = *(c->ret_value_ptr);
	r = ABT_rwlock_unlock(c->lock);
	MOBJECT_ASSERT(r == ABT_SUCCESS, "ABT_rwlock_unlock failed");
	return 0;
}

void mobject_store_aio_release(mobject_store_completion_t c)
{
	int r;
	if(c == MOBJECT_COMPLETION_NULL) return;
	r = ABT_eventual_free(c->eventual);
	MOBJECT_ASSERT(r == ABT_SUCCESS, "ABT_eventual_free failed");
	r = ABT_rwlock_free(c->lock);
	MOBJECT_ASSERT(r == ABT_SUCCESS, "ABT_rwlock_free failed");
	free(c);
}