refactoring

This commit is contained in:
Devaev Maxim 2018-09-18 02:46:36 +03:00
parent 8039d60ad5
commit dbe20ae6da
7 changed files with 52 additions and 41 deletions

View File

@ -21,9 +21,9 @@
static long double _capture_get_fluency_delay(struct device_t *dev, struct workers_pool_t *pool);
static int _capture_init_loop(struct device_t *dev, struct workers_pool_t *pool, sig_atomic_t *volatile global_stop);
static int _capture_init(struct device_t *dev, struct workers_pool_t *pool, sig_atomic_t *volatile global_stop);
static void _capture_init_workers(struct device_t *dev, struct workers_pool_t *pool, sig_atomic_t *volatile global_stop);
static int _capture_init_loop(struct device_t *dev, struct workers_pool_t *pool);
static int _capture_init(struct device_t *dev, struct workers_pool_t *pool);
static void _capture_init_workers(struct device_t *dev, struct workers_pool_t *pool);
static void *_capture_worker_thread(void *v_ctx);
static void _capture_destroy_workers(struct device_t *dev, struct workers_pool_t *pool);
static int _capture_control(struct device_t *dev, const bool enable);
@ -68,17 +68,17 @@ static void _capture_dump(struct captured_picture_t *captured) {
}
#endif
void capture_loop(struct device_t *dev, struct captured_picture_t *captured, sig_atomic_t *volatile global_stop) {
void capture_loop(struct device_t *dev, struct captured_picture_t *captured) {
struct workers_pool_t pool;
volatile sig_atomic_t workers_stop;
bool workers_stop;
MEMSET_ZERO(pool);
pool.workers_stop = (sig_atomic_t *volatile)&workers_stop;
pool.workers_stop = &workers_stop;
LOG_INFO("Using V4L2 device: %s", dev->path);
LOG_INFO("Using JPEG quality: %d%%", dev->jpeg_quality);
while (_capture_init_loop(dev, &pool, global_stop) == 0) {
while (_capture_init_loop(dev, &pool) == 0) {
struct worker_t *last_worker = NULL;
unsigned frames_count = 0;
long double grab_after = 0;
@ -92,7 +92,7 @@ void capture_loop(struct device_t *dev, struct captured_picture_t *captured, sig
captured->width = dev->run->width;
captured->height = dev->run->height;
while (!*global_stop) {
while (!dev->stop) {
SEP_DEBUG('-');
LOG_DEBUG("Waiting for workers ...");
@ -118,7 +118,7 @@ void capture_loop(struct device_t *dev, struct captured_picture_t *captured, sig
# endif
}
if (*global_stop) {
if (dev->stop) {
break;
}
@ -250,6 +250,10 @@ void capture_loop(struct device_t *dev, struct captured_picture_t *captured, sig
device_close(dev);
}
void capture_loop_break(struct device_t *dev) {
dev->stop = 1;
}
static long double _capture_get_fluency_delay(struct device_t *dev, struct workers_pool_t *pool) {
long double delay = 0;
@ -264,12 +268,12 @@ static long double _capture_get_fluency_delay(struct device_t *dev, struct worke
return delay / dev->run->n_buffers / dev->run->n_buffers;
}
static int _capture_init_loop(struct device_t *dev, struct workers_pool_t *pool, sig_atomic_t *volatile global_stop) {
static int _capture_init_loop(struct device_t *dev, struct workers_pool_t *pool) {
int retval = -1;
LOG_DEBUG("%s: global_stop = %d", __FUNCTION__, *global_stop);
while (!*global_stop) {
if ((retval = _capture_init(dev, pool, global_stop)) < 0) {
LOG_DEBUG("%s: *dev->stop = %d", __FUNCTION__, dev->stop);
while (!dev->stop) {
if ((retval = _capture_init(dev, pool)) < 0) {
LOG_INFO("Sleeping %d seconds before new capture init ...", dev->error_timeout);
sleep(dev->error_timeout);
} else {
@ -279,7 +283,7 @@ static int _capture_init_loop(struct device_t *dev, struct workers_pool_t *pool,
return retval;
}
static int _capture_init(struct device_t *dev, struct workers_pool_t *pool, sig_atomic_t *volatile global_stop) {
static int _capture_init(struct device_t *dev, struct workers_pool_t *pool) {
SEP_INFO('=');
_capture_destroy_workers(dev, pool);
@ -292,7 +296,7 @@ static int _capture_init(struct device_t *dev, struct workers_pool_t *pool, sig_
if (_capture_control(dev, true) < 0) {
goto error;
}
_capture_init_workers(dev, pool, global_stop);
_capture_init_workers(dev, pool);
return 0;
@ -301,7 +305,7 @@ static int _capture_init(struct device_t *dev, struct workers_pool_t *pool, sig_
return -1;
}
static void _capture_init_workers(struct device_t *dev, struct workers_pool_t *pool, sig_atomic_t *volatile global_stop) {
static void _capture_init_workers(struct device_t *dev, struct workers_pool_t *pool) {
LOG_DEBUG("Spawning %d workers ...", dev->run->n_buffers);
*pool->workers_stop = false;
@ -316,7 +320,7 @@ static void _capture_init_workers(struct device_t *dev, struct workers_pool_t *p
pool->workers[index].ctx.index = index;
pool->workers[index].ctx.dev = dev;
pool->workers[index].ctx.global_stop = global_stop;
pool->workers[index].ctx.dev_stop = (sig_atomic_t *volatile)&dev->stop;
pool->workers[index].ctx.workers_stop = pool->workers_stop;
pool->workers[index].ctx.last_comp_time_mutex = &pool->workers[index].last_comp_time_mutex;
@ -339,7 +343,7 @@ static void *_capture_worker_thread(void *v_ctx) {
LOG_DEBUG("Hello! I am a worker #%d ^_^", ctx->index);
while (!*ctx->global_stop && !*ctx->workers_stop) {
while (!*ctx->dev_stop && !*ctx->workers_stop) {
A_PTHREAD_M_LOCK(ctx->has_free_workers_mutex);
*ctx->has_free_workers = true;
A_PTHREAD_M_UNLOCK(ctx->has_free_workers_mutex);

View File

@ -13,8 +13,8 @@ struct worker_context_t {
int index;
struct device_t *dev;
struct v4l2_buffer buf_info;
sig_atomic_t *volatile global_stop;
sig_atomic_t *volatile workers_stop;
sig_atomic_t *volatile dev_stop;
bool *workers_stop;
pthread_mutex_t *last_comp_time_mutex;
long double *last_comp_time;
@ -44,7 +44,7 @@ struct worker_t {
struct workers_pool_t {
struct worker_t *workers;
sig_atomic_t *volatile workers_stop;
bool *workers_stop;
pthread_mutex_t has_free_workers_mutex;
bool has_free_workers;
@ -63,4 +63,5 @@ struct captured_picture_t {
struct captured_picture_t *captured_picture_init();
void captured_picture_destroy(struct captured_picture_t *captured);
void capture_loop(struct device_t *dev, struct captured_picture_t *captured, sig_atomic_t *volatile global_stop);
void capture_loop(struct device_t *dev, struct captured_picture_t *capture);
void capture_loop_break(struct device_t *dev);

View File

@ -2,6 +2,7 @@
#include <stddef.h>
#include <stdbool.h>
#include <signal.h>
#include <linux/videodev2.h>
@ -45,7 +46,8 @@ struct device_t {
unsigned timeout;
unsigned error_timeout;
struct device_runtime_t *run;
struct device_runtime_t *run;
sig_atomic_t volatile stop;
};

View File

@ -1,5 +1,3 @@
#include <signal.h>
#include "capture.h"
#include "tools.h"
#include "http.h"
@ -23,6 +21,11 @@ void http_server_destroy(struct http_server_t *server) {
free(server);
}
void http_server_loop(struct http_server_t *server, struct captured_picture_t *captured, sig_atomic_t *volatile global_stop) {
void http_server_loop(struct http_server_t *server, struct captured_picture_t *captured) {
// TODO: implement server here
}
void http_server_loop_break(struct http_server_t *server) {
// TODO: implement stop here
}

View File

@ -1,5 +1,3 @@
#include <signal.h>
#include "tools.h"
#include "capture.h"
@ -13,4 +11,5 @@ struct http_server_t {
struct http_server_t *http_server_init();
void http_server_destroy(struct http_server_t *server);
void http_server_loop(struct http_server_t *server, struct captured_picture_t *captured, sig_atomic_t *volatile global_stop);
void http_server_loop(struct http_server_t *server, struct captured_picture_t *captured);
void http_server_loop_break(struct http_server_t *server);

View File

@ -103,13 +103,13 @@ static int _parse_options(int argc, char *argv[], struct device_t *dev, struct h
return 0;
}
struct thread_context {
struct main_context_t {
struct device_t *dev;
struct captured_picture_t *captured;
struct http_server_t *server;
};
static volatile sig_atomic_t _global_stop = 0;
static struct main_context_t *_ctx;
static void _block_thread_signals() {
sigset_t mask;
@ -119,23 +119,22 @@ static void _block_thread_signals() {
assert(!pthread_sigmask(SIG_BLOCK, &mask, NULL));
}
static void *_capture_loop_thread(void *v_ctx) {
struct thread_context *ctx = (struct thread_context *)v_ctx;
static void *_capture_loop_thread(UNUSED void *_) {
_block_thread_signals();
capture_loop(ctx->dev, ctx->captured, (sig_atomic_t *volatile)&_global_stop);
capture_loop(_ctx->dev, _ctx->captured);
return NULL;
}
static void *_server_loop_thread(void *v_ctx) {
struct thread_context *ctx = (struct thread_context *)v_ctx;
static void *_server_loop_thread(UNUSED void *_) {
_block_thread_signals();
http_server_loop(ctx->server, ctx->captured, (sig_atomic_t *volatile)&_global_stop);
http_server_loop(_ctx->server, _ctx->captured);
return NULL;
}
static void _signal_handler(int signum) {
LOG_INFO("===== Stopping by %s =====", strsignal(signum));
_global_stop = 1;
capture_loop_break(_ctx->dev);
http_server_loop_break(_ctx->server);
}
static void _install_signal_handlers() {
@ -168,14 +167,15 @@ int main(int argc, char *argv[]) {
pthread_t capture_loop_tid;
pthread_t server_loop_tid;
struct thread_context ctx;
struct main_context_t ctx;
ctx.dev = dev;
ctx.captured = captured;
ctx.server = server;
_ctx = &ctx;
A_PTHREAD_CREATE(&capture_loop_tid, _capture_loop_thread, (void *)&ctx);
A_PTHREAD_CREATE(&server_loop_tid, _server_loop_thread, (void *)&ctx);
A_PTHREAD_CREATE(&capture_loop_tid, _capture_loop_thread, NULL);
A_PTHREAD_CREATE(&server_loop_tid, _server_loop_thread, NULL);
A_PTHREAD_JOIN(capture_loop_tid);
A_PTHREAD_JOIN(server_loop_tid);
}

View File

@ -72,6 +72,8 @@ unsigned log_level;
#define INLINE inline __attribute__((always_inline))
#define UNUSED __attribute__((unused))
#define XIOCTL_RETRIES 4