Commit 2b79e3a5 authored by Éric Thiébaut's avatar Éric Thiébaut
Browse files

Complete rewrite of error handling

parent 1d5f32b8
......@@ -23,10 +23,14 @@
## Things to do
* Compile with good optimization flags by default:
`-DNDEBUG -O3 -fomit-frame-pointer -mavx2 -mfma`.
* Compile `copy.c`, preprocessing, etc. with good optimization flags by
default: `-DNDEBUG -O3 -fomit-frame-pointer -mavx2 -mfma`.
* Use per-thread data to simplify error management.
* Use per-thread data to simplify error management. `tao_report_errors` shall
use the error handler.
* Use enum constants `TAO_READ_ONLY` and `TAO_READ_WRITE` to lock r/w locks.
This may yield more readable code.
* Use `inline` which is an allowed keyword in standard C99 (see
http://www.drdobbs.com/the-new-c-inline-functions/184401540 for usage).
......
......@@ -102,8 +102,7 @@ get_error_details(int code, const char** mesg, const char** name)
}
}
void
alpao_push_error(tao_error_t** errs, const char* func)
void alpao_push_error(const char* func)
{
const int len = 255;
int status;
......@@ -117,10 +116,10 @@ alpao_push_error(tao_error_t** errs, const char* func)
mesg[len] = '\0';
for (int i = 0; errors[i].name != NULL; ++i) {
if (errors[i].code == code) {
/* The error message is different than expected, print a
warning and clone the error message to avoid another
warning and yet provide the correct error message and
number. This memory will never be returned.... */
// The error message is different than expected, print a
// warning and clone the error message to avoid another
// warning and yet provide the correct error message and
// number. This memory will never be returned....
if (strcmp(mesg, errors[i].mesg) != 0) {
warn("Alpao error message is now \"%s\", "
"it was \"%s\" (code = 0x%04d)",
......@@ -137,7 +136,7 @@ alpao_push_error(tao_error_t** errs, const char* func)
}
}
}
tao_push_other_error(errs, func, code, get_error_details);
tao_push_other_error(func, code, get_error_details);
}
static void
......@@ -171,7 +170,7 @@ static void overwrite_long(const long* ptr, long val);
alpao_open_mirror() in two functions using pointers to store other returned
values than the device handle. */
static asdkDM*
open_mirror(tao_error_t** errs, const char* func, const char* filename,
open_mirror(const char* func, const char* filename,
long* numberptr, char** serialptr)
{
char* serial; /* base name part of filename */
......@@ -184,7 +183,7 @@ open_mirror(tao_error_t** errs, const char* func, const char* filename,
/* Determine the location of the mirror configuration file. */
if (filename == NULL || filename[0] == '\0' ||
strlen(filename) >= sizeof(path)) {
tao_push_error(errs, func, TAO_BAD_SERIAL);
tao_push_error(func, TAO_BAD_SERIAL);
return NULL;
}
strcpy(path, filename);
......@@ -200,11 +199,11 @@ open_mirror(tao_error_t** errs, const char* func, const char* filename,
dirname = path;
serial = ptr + 1;
if (getcwd(workdir, sizeof(workdir)) == NULL) {
tao_push_system_error(errs, "getcwd");
tao_push_system_error("getcwd");
return NULL;
}
if (chdir(path) != 0) {
tao_push_system_error(errs, "chdir");
tao_push_system_error("chdir");
return NULL;
}
}
......@@ -216,7 +215,7 @@ open_mirror(tao_error_t** errs, const char* func, const char* filename,
}
*serialptr = strdup(serial);
if (*serialptr == NULL) {
tao_push_system_error(errs, "strdup");
tao_push_system_error("strdup");
return NULL;
}
......@@ -224,30 +223,30 @@ open_mirror(tao_error_t** errs, const char* func, const char* filename,
checking for errors. */
handle = asdkInit(serial);
if (dirname != NULL && chdir(workdir) != 0) {
tao_push_system_error(errs, "chdir");
tao_push_system_error("chdir");
goto error;
}
if (handle == NULL) {
alpao_push_error(errs, func);
alpao_push_error(func);
goto error;
}
/* Retrieve the number of actuators. */
double val;
if (asdkGet((asdkDM*)handle, "NbOfActuator", &val) != SUCCESS) {
alpao_push_error(errs, func);
alpao_push_error(func);
goto error;
}
long number = lround(val);
if (number <= 0 || number != val) {
tao_push_error(errs, func, TAO_BAD_SIZE);
tao_push_error(func, TAO_BAD_SIZE);
goto error;
}
*numberptr = number;
/* Disables the throwing of an exception on error. */
if (asdkSet(handle, "UseException", 0) != SUCCESS) {
alpao_push_error(errs, func);
alpao_push_error(func);
goto error;
}
return handle;
......@@ -262,11 +261,9 @@ error:
return NULL;
}
alpao_mirror_t*
alpao_open_mirror(tao_error_t** errs,
const char* filename,
const char* owner,
unsigned int perms)
alpao_mirror_t* alpao_open_mirror(const char* filename,
const char* owner,
unsigned int perms)
{
/* Local variables. */
char* serial;
......@@ -281,12 +278,12 @@ alpao_open_mirror(tao_error_t** errs,
} else if (sizeof(Scalar) == sizeof(float)) {
eltype = TAO_FLOAT;
} else {
tao_push_error(errs, __func__, TAO_BAD_TYPE);
tao_push_error(__func__, TAO_BAD_TYPE);
return NULL;
}
/* Open device to mirror. */
handle = open_mirror(errs, __func__, filename, &number, &serial);
handle = open_mirror(__func__, filename, &number, &serial);
if (handle == NULL) {
return NULL;
}
......@@ -295,7 +292,7 @@ alpao_open_mirror(tao_error_t** errs,
space for temporary commands. */
long offset = TAO_ROUND_UP(sizeof(alpao_mirror_t), ALIGNMENT);
long size = offset + number*sizeof(Scalar);
dm = tao_malloc(errs, size);
dm = tao_malloc(size);
if (dm == NULL) {
free(serial);
asdkRelease(handle);
......@@ -303,7 +300,6 @@ alpao_open_mirror(tao_error_t** errs,
}
memset(dm, 0, size);
dm->handle = handle;
dm->errs = TAO_NO_ERRORS;
dm->current = (void*)tao_get_shared_mirror_current_commands(dm->shared);
dm->scheduled = (void*)tao_get_shared_mirror_scheduled_commands(dm->shared);
dm->temporary = TAO_COMPUTED_ADDRESS(dm, offset);
......@@ -311,7 +307,7 @@ alpao_open_mirror(tao_error_t** errs,
dm->number = number;
/* Allocate a TAO shared mirror. */
dm->shared = tao_create_shared_mirror(errs, owner, eltype, number, perms);
dm->shared = tao_create_shared_mirror(owner, eltype, number, perms);
if (dm->shared == NULL) {
alpao_close_mirror(dm);
return NULL;
......@@ -328,21 +324,17 @@ alpao_close_mirror(alpao_mirror_t* dm)
dm->handle = NULL;
}
if (dm->shared != NULL) {
tao_detach_shared_mirror(&dm->errs, dm->shared);
tao_detach_shared_mirror(dm->shared);
dm->shared = NULL;
}
if (TAO_ANY_ERRORS(&dm->errs)) {
if (dm->debuglevel > 0) {
tao_report_errors(&dm->errs);
} else {
tao_discard_errors(&dm->errs);
}
}
if (dm->serial != NULL) {
free((void*)dm->serial);
dm->serial = NULL;
}
free(dm);
if (tao_any_errors()) {
tao_report_errors();
}
}
}
......@@ -352,58 +344,58 @@ alpao_close_mirror(alpao_mirror_t* dm)
// int
// alpao_lock_mirror(alpao_mirror_t* dm)
// {
// return tao_lock_mutex(&dm->errs, &MUTEX(dm));
// return tao_lock_mutex(&MUTEX(dm));
// }
//
// int
// alpao_try_lock_mirror(alpao_mirror_t* dm)
// {
// return tao_try_lock_mutex(&dm->errs, &MUTEX(dm));
// return tao_try_lock_mutex(&MUTEX(dm));
// }
//
// tao_status_t
// alpao_abstimed_lock_mirror(alpao_mirror_t* dm,
// const struct timespec* abstime)
// {
// return tao_abstimed_lock_mutex(&dm->errs, &MUTEX(dm), abstime);
// return tao_abstimed_lock_mutex(&MUTEX(dm), abstime);
// }
//
// tao_status_t
// alpao_timed_lock_mirror(alpao_mirror_t* dm, double secs)
// {
// return tao_timed_lock_mutex(&dm->errs, &MUTEX(dm), secs);
// return tao_timed_lock_mutex(&MUTEX(dm), secs);
// }
//
// int
// alpao_unlock_mirror(alpao_mirror_t* dm)
// {
// return tao_unlock_mutex(&dm->errs, &MUTEX(dm));
// return tao_unlock_mutex(&MUTEX(dm));
// }
//
// int
// alpao_signal_mirror(alpao_mirror_t* dm)
// {
// return tao_signal_condition(&dm->errs, &CONDVAR(dm));
// return tao_signal_condition(&CONDVAR(dm));
// }
//
// int
// alpao_wait_mirror(alpao_mirror_t* dm)
// {
// return tao_wait_condition(&dm->errs, &CONDVAR(dm), &MUTEX(dm));
// return tao_wait_condition(&CONDVAR(dm), &MUTEX(dm));
// }
//
// tao_status_t
// alpao_abstimed_wait_mirror(alpao_mirror_t* dm,
// const struct timespec* abstime)
// {
// return tao_abstimed_wait_condition(&dm->errs, &CONDVAR(dm),
// return tao_abstimed_wait_condition(&CONDVAR(dm),
// &MUTEX(dm), abstime);
// }
//
// tao_status_t
// alpao_timed_wait_mirror(alpao_mirror_t* dm, double secs)
// {
// return tao_timed_wait_condition(&dm->errs, &CONDVAR(dm),
// return tao_timed_wait_condition(&CONDVAR(dm),
// &MUTEX(dm), secs);
// }
......@@ -420,7 +412,7 @@ alpao_apply_scheduled_commands(alpao_mirror_t* dm)
dest[i] = CLAMP(val, vmin, vmax);
}
if (asdkSend((asdkDM*)dm->handle, dest) != SUCCESS) {
alpao_push_error(&dm->errs, __func__);
alpao_push_error(__func__);
return TAO_ERROR;
}
memcpy(dm->current, dest, n*sizeof(Scalar));
......@@ -433,7 +425,7 @@ tao_status_t
alpao_reset_mirror(alpao_mirror_t* dm)
{
if (asdkReset((asdkDM*)dm->handle) != SUCCESS) {
alpao_push_error(&dm->errs, __func__);
alpao_push_error(__func__);
return TAO_ERROR;
}
memset(dm->current, 0, dm->number*sizeof(Scalar));
......@@ -446,7 +438,7 @@ alpao_stop_mirror(alpao_mirror_t* dm)
{
/* FIXME: reflect changes to others? */
if (asdkStop((asdkDM*)dm->handle) != SUCCESS) {
alpao_push_error(&dm->errs, __func__);
alpao_push_error(__func__);
return TAO_ERROR;
}
return TAO_OK;
......@@ -533,7 +525,7 @@ find_attribute(alpao_mirror_t* dm, const char* func, const char* key)
}
}
}
tao_push_error(&dm->errs, func, TAO_BAD_NAME);
tao_push_error(func, TAO_BAD_NAME);
return -1;
}
......@@ -546,15 +538,15 @@ alpao_get_boolean_attribute(alpao_mirror_t* dm, const char* key, bool* ptr)
return TAO_ERROR;
}
if ((attributes[i].flags & READABLE) == 0) {
tao_push_error(&dm->errs, __func__, TAO_UNREADABLE);
tao_push_error(__func__, TAO_UNREADABLE);
return TAO_ERROR;
}
if ((attributes[i].flags & BOOLEAN) == 0) {
tao_push_error(&dm->errs, __func__, TAO_BAD_TYPE);
tao_push_error(__func__, TAO_BAD_TYPE);
return TAO_ERROR;
}
if (asdkGet((asdkDM*)dm->handle, key, &val) != SUCCESS) {
alpao_push_error(&dm->errs, __func__);
alpao_push_error(__func__);
return TAO_ERROR;
}
*ptr = (val ? true : false);
......@@ -570,15 +562,15 @@ alpao_get_integer_attribute(alpao_mirror_t* dm, const char* key, long* ptr)
return TAO_ERROR;
}
if ((attributes[i].flags & READABLE) == 0) {
tao_push_error(&dm->errs, __func__, TAO_UNREADABLE);
tao_push_error(__func__, TAO_UNREADABLE);
return TAO_ERROR;
}
if ((attributes[i].flags & INTEGER) == 0) {
tao_push_error(&dm->errs, __func__, TAO_BAD_TYPE);
tao_push_error(__func__, TAO_BAD_TYPE);
return TAO_ERROR;
}
if (asdkGet((asdkDM*)dm->handle, key, &val) != SUCCESS) {
alpao_push_error(&dm->errs, __func__);
alpao_push_error(__func__);
return TAO_ERROR;
}
*ptr = lround(val);
......@@ -594,15 +586,15 @@ alpao_get_real_attribute(alpao_mirror_t* dm, const char* key, double* ptr)
return TAO_ERROR;
}
if ((attributes[i].flags & READABLE) == 0) {
tao_push_error(&dm->errs, __func__, TAO_UNREADABLE);
tao_push_error(__func__, TAO_UNREADABLE);
return TAO_ERROR;
}
if ((attributes[i].flags & FLOAT) == 0) {
tao_push_error(&dm->errs, __func__, TAO_BAD_TYPE);
tao_push_error(__func__, TAO_BAD_TYPE);
return TAO_ERROR;
}
if (asdkGet((asdkDM*)dm->handle, key, &val) != SUCCESS) {
alpao_push_error(&dm->errs, __func__);
alpao_push_error(__func__);
return TAO_ERROR;
}
*ptr = val;
......@@ -617,15 +609,15 @@ alpao_set_boolean_attribute(alpao_mirror_t* dm, const char* key, bool val)
return TAO_ERROR;
}
if ((attributes[i].flags & WRITABLE) == 0) {
tao_push_error(&dm->errs, __func__, TAO_UNWRITABLE);
tao_push_error(__func__, TAO_UNWRITABLE);
return TAO_ERROR;
}
if ((attributes[i].flags & BOOLEAN) == 0) {
tao_push_error(&dm->errs, __func__, TAO_BAD_TYPE);
tao_push_error(__func__, TAO_BAD_TYPE);
return TAO_ERROR;
}
if (asdkSet((asdkDM*)dm->handle, key, (val ? 1 : 0)) != SUCCESS) {
alpao_push_error(&dm->errs, __func__);
alpao_push_error(__func__);
return TAO_ERROR;
}
return TAO_OK;
......@@ -639,15 +631,15 @@ alpao_set_integer_attribute(alpao_mirror_t* dm, const char* key, long val)
return TAO_ERROR;
}
if ((attributes[i].flags & WRITABLE) == 0) {
tao_push_error(&dm->errs, __func__, TAO_UNWRITABLE);
tao_push_error(__func__, TAO_UNWRITABLE);
return TAO_ERROR;
}
if ((attributes[i].flags & INTEGER) == 0) {
tao_push_error(&dm->errs, __func__, TAO_BAD_TYPE);
tao_push_error(__func__, TAO_BAD_TYPE);
return TAO_ERROR;
}
if (asdkSet((asdkDM*)dm->handle, key, val) != SUCCESS) {
alpao_push_error(&dm->errs, __func__);
alpao_push_error(__func__);
return TAO_ERROR;
}
return TAO_OK;
......@@ -661,15 +653,15 @@ alpao_set_real_attribute(alpao_mirror_t* dm, const char* key, double val)
return TAO_ERROR;
}
if ((attributes[i].flags & WRITABLE) == 0) {
tao_push_error(&dm->errs, __func__, TAO_UNWRITABLE);
tao_push_error(__func__, TAO_UNWRITABLE);
return TAO_ERROR;
}
if ((attributes[i].flags & FLOAT) == 0) {
tao_push_error(&dm->errs, __func__, TAO_BAD_TYPE);
tao_push_error(__func__, TAO_BAD_TYPE);
return TAO_ERROR;
}
if (asdkSet((asdkDM*)dm->handle, key, val) != SUCCESS) {
alpao_push_error(&dm->errs, __func__);
alpao_push_error(__func__);
return TAO_ERROR;
}
return TAO_OK;
......@@ -684,16 +676,16 @@ alpao_set_string_attribute(alpao_mirror_t* dm, const char* key,
return TAO_ERROR;
}
if ((attributes[i].flags & WRITABLE) == 0) {
tao_push_error(&dm->errs, __func__, TAO_UNWRITABLE);
tao_push_error(__func__, TAO_UNWRITABLE);
return TAO_ERROR;
}
if ((attributes[i].flags & STRING) == 0) {
tao_push_error(&dm->errs, __func__, TAO_BAD_TYPE);
tao_push_error(__func__, TAO_BAD_TYPE);
return TAO_ERROR;
}
if (asdkSetString((asdkDM*)dm->handle, key,
(str == NULL ? "" : str)) != SUCCESS) {
alpao_push_error(&dm->errs, __func__);
alpao_push_error(__func__);
return TAO_ERROR;
}
return TAO_OK;
......
......@@ -46,7 +46,6 @@ typedef struct _alpao_mirror alpao_mirror_t;
struct _alpao_mirror {
void* handle;/**< Handle to device. */
tao_error_t* errs;/**< Error stack. */
tao_shared_mirror_t* shared;/**< Attached shared mirror. */
void* current;/**< Pointer to current commands. */
void* scheduled;/**< Pointer to scheduled commands. */
......@@ -59,50 +58,38 @@ struct _alpao_mirror {
/**
* Open Alpao deformable mirror.
*/
extern alpao_mirror_t*
alpao_open_mirror(tao_error_t** errs,
const char* filename,
const char* owner,
unsigned int perms);
extern alpao_mirror_t* alpao_open_mirror(const char* filename,
const char* owner,
unsigned int perms);
/**
* Close Alpao deformable mirror.
*
* Caller must have unlocked the mirror.
*/
extern void
alpao_close_mirror(alpao_mirror_t* dm);
extern void alpao_close_mirror(alpao_mirror_t* dm);
extern tao_status_t
alpao_lock_mirror(alpao_mirror_t* dm);
extern tao_status_t alpao_lock_mirror(alpao_mirror_t* dm);
extern tao_status_t
alpao_try_lock_mirror(alpao_mirror_t* dm);
extern tao_status_t alpao_try_lock_mirror(alpao_mirror_t* dm);
extern tao_status_t
alpao_abstimed_lock_mirror(alpao_mirror_t* dm,
const struct timespec* abstime);
extern tao_status_t alpao_abstimed_lock_mirror(alpao_mirror_t* dm,
const struct timespec* abstime);
extern tao_status_t
alpao_timed_lock_mirror(alpao_mirror_t* dm,
double secs);
extern tao_status_t alpao_timed_lock_mirror(alpao_mirror_t* dm,
double secs);
extern tao_status_t
alpao_unlock_mirror(alpao_mirror_t* dm);
extern tao_status_t alpao_unlock_mirror(alpao_mirror_t* dm);
extern tao_status_t
alpao_signal_mirror(alpao_mirror_t* dm);
extern tao_status_t alpao_signal_mirror(alpao_mirror_t* dm);
extern tao_status_t
alpao_wait_mirror(alpao_mirror_t* dm);
extern tao_status_t alpao_wait_mirror(alpao_mirror_t* dm);
extern tao_status_t
alpao_abstimed_wait_mirror(alpao_mirror_t* dm,
const struct timespec* abstime);
extern tao_status_t alpao_abstimed_wait_mirror(alpao_mirror_t* dm,
const struct timespec* abstime);
extern tao_status_t
alpao_timed_wait_mirror(alpao_mirror_t* dm,
double secs);
extern tao_status_t alpao_timed_wait_mirror(alpao_mirror_t* dm,
double secs);
/**
* Apply the scheduled command of an Alpao deformable mirror.
......@@ -110,8 +97,7 @@ alpao_timed_wait_mirror(alpao_mirror_t* dm,
* To maintain the consistency of the shared information, the caller shall have
* locked the mirror.
*/
extern tao_status_t
alpao_apply_scheduled_commands(alpao_mirror_t* dm);
extern tao_status_t alpao_apply_scheduled_commands(alpao_mirror_t* dm);
/**
* Stop Alpao deformable mirror.
......@@ -119,8 +105,7 @@ alpao_apply_scheduled_commands(alpao_mirror_t* dm);
* To maintain the consistency of the shared information, the caller shall have
* locked the mirror.
*/
extern tao_status_t
alpao_stop_mirror(alpao_mirror_t* dm);
extern tao_status_t alpao_stop_mirror(alpao_mirror_t* dm);
/**
* Stop Alpao deformable mirror.
......@@ -128,71 +113,61 @@ alpao_stop_mirror(alpao_mirror_t* dm);
* To maintain the consistency of the shared information, the caller shall have
* locked the mirror.
*/
extern tao_status_t
alpao_reset_mirror(alpao_mirror_t* dm);
extern tao_status_t alpao_reset_mirror(alpao_mirror_t* dm);
/**
* Get the value of a boolean attribute of an Alpao mirror.
*/
extern tao_status_t
alpao_get_boolean_attribute(alpao_mirror_t* dm,
const char* key,
bool* ptr);
extern tao_status_t alpao_get_boolean_attribute(alpao_mirror_t* dm,
const char* key,
bool* ptr);
/**
* Get the value of an integer attribute of an Alpao mirror.
*/
extern tao_status_t
alpao_get_integer_attribute(alpao_mirror_t* dm,
const char* key,
long* ptr);
extern tao_status_t alpao_get_integer_attribute(alpao_mirror_t* dm,
const char* key,
long* ptr);
/**
* Get the value of a floating-point attribute of an Alpao mirror.
*/
extern tao_status_t
alpao_get_real_attribute(alpao_mirror_t* dm,
const char* key,
double* ptr);
extern tao_status_t alpao_get_real_attribute(alpao_mirror_t* dm,
const char* key,
double* ptr);
/**
* Set the value of a boolean attribute of an Alpao mirror.
*/
extern tao_status_t
alpao_set_boolean_attribute(alpao_mirror_t* dm,
const char* key,
bool val);
extern tao_status_t alpao_set_boolean_attribute(alpao_mirror_t* dm,
const char* key,
bool val);
/**
* Set the value of an integer attribute of an Alpao mirror.
*/
extern tao_status_t
alpao_set_integer_attribute(alpao_mirror_t* dm,
const char* key,
long val);
extern tao_status_t alpao_set_integer_attribute(alpao_mirror_t* dm,
const char* key,
long val);
/**
* Set the value of a floating-point attribute of an Alpao mirror.
*/
extern tao_status_t
alpao_set_real_attribute(alpao_mirror_t* dm,
const char* key,
double val);
extern tao_status_t alpao_set_real_attribute(alpao_mirror_t* dm,
const char* key,
double val);
/**
* Set the value of a textual attribute of an Alpao mirror.
*/
extern tao_status_t
alpao_set_string_attribute(alpao_mirror_t* dm,
const char* key,
const char* str);
extern tao_status_t alpao_set_string_attribute(alpao_mirror_t* dm,
const char* key,
const char* str);
/**
* Push last Alpao error on error stack.
* Push last Alpao error on calling thread error stack.
*/
extern void
alpao_push_error(tao_error_t** errs,
const char* func);
extern void alpao_push_error(const char* func);
/** @} */