Commit 1bad019d authored by Éric Thiébaut's avatar Éric Thiébaut
Browse files

The on_finalize method returns a status

parent 5458072a
......@@ -173,7 +173,7 @@ tao_status andor_initialize(
static tao_status on_initialize(
tao_camera* cam);
static void on_finalize(
static tao_status on_finalize(
tao_camera* cam);
static tao_status on_reset(
......@@ -425,7 +425,7 @@ error:
// freeing more than once. This is to allow calling this method several times
// with no damages. Acquisitions buffers are destroyed by the caller after
// calling this virtual method.
static void on_finalize(
static tao_status on_finalize(
tao_camera* cam)
{
assert(cam != NULL);
......@@ -436,6 +436,7 @@ static void on_finalize(
(void)AT_Close(dev->handle);
dev->handle = AT_HANDLE_SYSTEM;
}
return TAO_ERROR;
}
static tao_status on_reset(
......
......@@ -229,31 +229,45 @@ tao_camera* tao_camera_create(
tao_status tao_camera_destroy(
tao_camera* cam)
{
tao_status status = TAO_OK;
if (cam != NULL) {
// Lock the camera.
pthread_mutex_lock(&cam->mutex);
status = tao_mutex_lock(&cam->mutex);
bool locked = (status == TAO_OK);
// Stop acquisition if acquiring (ignoring errors).
if (cam->runlevel == 2) {
cam->ops->stop(cam);
if (cam->ops->stop(cam) != TAO_OK) {
status = TAO_ERROR;
}
cam->runlevel = 1;
}
// Call virtual "finalize" method.
cam->ops->finalize(cam);
cam->runlevel = 4;
if (cam->runlevel < 4) {
if (cam->ops->finalize(cam) != TAO_OK) {
status = TAO_ERROR;
}
cam->runlevel = 4;
}
// Destroy condition variable.
pthread_cond_destroy(&cam->cond);
if (tao_condition_destroy(&cam->cond) != TAO_OK) {
status = TAO_ERROR;
}
// Unlock the camera and immediately destroy its mutex.
pthread_mutex_unlock(&cam->mutex);
pthread_mutex_destroy(&cam->mutex);
if (locked && tao_mutex_unlock(&cam->mutex) != TAO_OK) {
status = TAO_ERROR;
}
if (tao_mutex_destroy(&cam->mutex, true) != TAO_OK) {
status = TAO_ERROR;
}
// Eventually release memory storing the instance.
free((void*)cam);
}
return TAO_OK;
return status;
}
tao_status tao_camera_lock(
......
......@@ -80,7 +80,7 @@ struct tao_camera_ops_ {
/// resources are destroyed in case of failure (the `finalize` method is
/// not called if initialization fails).
void (*finalize)(
tao_status (*finalize)(
tao_camera* cam);
///< Free device resources. This method is only called once at the end of
/// the lifetime of the camera instance. This method is not called by the
......
......@@ -117,16 +117,16 @@ static tao_status on_wait_buffer(
int drop);
static tao_camera_ops ops = {
.name = "FooCamera", // FIXME: Change the name!
.initialize = on_initialize,
.finalize = on_finalize,
.reset = on_reset,
.name = "FooCamera", // FIXME: Change the name!
.initialize = on_initialize,
.finalize = on_finalize,
.reset = on_reset,
.update_config = on_update_config,
.check_config = on_check_config,
.set_config = on_set_config,
.start = on_start,
.stop = on_stop,
.wait_buffer: on_wait_buffer
.check_config = on_check_config,
.set_config = on_set_config,
.start = on_start,
.stop = on_stop,
.wait_buffer = on_wait_buffer
};
//-----------------------------------------------------------------------------
......
......@@ -44,15 +44,13 @@ static tao_status check_regions_of_interest(
long sensorheight);
static tao_status stop_acquisition(
phnx_device* dev,
bool throwerrors);
phnx_device* dev);
static tao_status connect_camera(
phnx_device* dev);
static tao_status disconnect_camera(
phnx_device* dev,
bool throwerrors);
phnx_device* dev);
//-----------------------------------------------------------------------------
// TABLE OF KNOWN CAMERAS
......@@ -70,7 +68,7 @@ static phnx_operations const * const known_cameras[] = {
static tao_status on_initialize(
tao_camera* cam);
static void on_finalize(
static tao_status on_finalize(
tao_camera* cam);
static tao_status on_reset(
......@@ -102,16 +100,16 @@ static tao_status on_wait_buffer(
// Table of operations of all Phoenix cameras. It address can be used to
// assert that a given TAO camera belongs to this family.
static tao_camera_ops ops = {
"Phoenix",
on_initialize,
on_finalize,
on_reset,
on_update_config,
on_check_config,
on_set_config,
on_start,
on_stop,
on_wait_buffer,
.name = "Phoenix",
.initialize = on_initialize,
.finalize = on_finalize,
.reset = on_reset,
.update_config = on_update_config,
.check_config = on_check_config,
.set_config = on_set_config,
.start = on_start,
.stop = on_stop,
.wait_buffer = on_wait_buffer
};
//-----------------------------------------------------------------------------
......@@ -347,30 +345,35 @@ static tao_status on_initialize(
// Finalize a "Phoenix" device. Stop acquisition, close the Phoenix board and
// destroy the Phoenix handle. No errors are reported (unless in debug mode).
static void on_finalize(
static tao_status on_finalize(
tao_camera* cam)
{
assert(cam != NULL);
assert(cam->ops == &ops);
tao_status status = TAO_OK;
phnx_device* dev = (phnx_device*)cam;
if (cam->runlevel == 2) {
(void)stop_acquisition(dev, false);
if (stop_acquisition(dev) != TAO_OK) {
status = TAO_ERROR;
}
cam->runlevel = 1;
}
if (cam->runlevel >= 1) {
(void)disconnect_camera(dev, false);
if (cam->runlevel >= 1 && cam->runlevel < 4) {
if (disconnect_camera(dev) != TAO_OK) {
status = TAO_ERROR;
}
cam->runlevel = 4;
}
manage_buffer_info_list(dev, 0);
assert(sizeof(dev->handle) >= sizeof(tHandle));
tHandle handle = dev->handle;
etStat code = PHX_Destroy(&handle);
dev->handle = handle;
#ifdef PHNX_DEBUG
if (code != PHX_OK) {
fprintf(stderr,
"PHX_Destroy failed with status %d in %s (%s:%d)\n",
(int)code, __func__, __FILE__, __LINE__);
phx_error("PHX_Destroy", code);
status = TAO_ERROR;
}
#endif // PHNX_DEBUG
return status;
}
// Manage to revert to run-level 1. Should only be called when run-level is 3
......@@ -382,7 +385,7 @@ static tao_status on_reset(
assert(cam->ops == &ops);
assert(cam->runlevel == 3);
phnx_device* dev = (phnx_device*)cam;
if (disconnect_camera(dev, true) != TAO_OK ||
if (disconnect_camera(dev) != TAO_OK ||
connect_camera(dev) != TAO_OK) {
cam->runlevel = 4;
return TAO_ERROR;
......@@ -687,7 +690,7 @@ static tao_status on_stop(
// run-level 1 ("waiting").
assert(cam->ops == &ops);
assert(cam->runlevel == 2);
return stop_acquisition((phnx_device*)cam, true);
return stop_acquisition((phnx_device*)cam);
}
......@@ -912,8 +915,7 @@ static void acquisition_callback(
// Stop acquisition immediately.
static tao_status stop_acquisition(
phnx_device* dev,
bool throwerrors)
phnx_device* dev)
{
// Since we use acquisition buffers allocated by the frame-grabber, we
// cannot be sure that they will be available after acquisition has been
......@@ -926,16 +928,16 @@ static tao_status stop_acquisition(
// ignored for the `PHX_UNLOCK` command.
tao_status status = TAO_OK;
etStat code = PHX_StreamRead(dev->handle, PHX_ABORT, NULL);
if (code != PHX_OK && throwerrors) {
if (code != PHX_OK) {
phx_error("PHX_StreamRead(PHX_ABORT)", code);
status = TAO_ERROR;
}
code = PHX_StreamRead(dev->handle, PHX_UNLOCK, NULL);
if (code != PHX_OK && code != PHX_ERROR_NOT_IMPLEMENTED && throwerrors) {
if (code != PHX_OK && code != PHX_ERROR_NOT_IMPLEMENTED) {
phx_error("PHX_StreamRead(PHX_UNLOCK)", code);
status = TAO_ERROR;
}
if (dev->ops->stop != NULL && dev->ops->stop(dev) != TAO_OK && throwerrors) {
if (dev->ops->stop != NULL && dev->ops->stop(dev) != TAO_OK) {
status = TAO_ERROR;
}
return status;
......@@ -995,14 +997,13 @@ static tao_status connect_camera(
// Disconnect the camera, that is close the Phoenix board.
static tao_status disconnect_camera(
phnx_device* dev,
bool throwerrors)
phnx_device* dev)
{
assert(sizeof(dev->handle) >= sizeof(tHandle));
tHandle handle = dev->handle;
etStat code = PHX_Close(&handle);
dev->handle = handle;
if (code != PHX_OK && throwerrors) {
if (code != PHX_OK) {
phx_error("PHX_Close", code);
return TAO_ERROR;
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment