summaryrefslogtreecommitdiffstats
path: root/tinySAK/src/tsk_runnable.h
diff options
context:
space:
mode:
Diffstat (limited to 'tinySAK/src/tsk_runnable.h')
-rw-r--r--tinySAK/src/tsk_runnable.h167
1 files changed, 167 insertions, 0 deletions
diff --git a/tinySAK/src/tsk_runnable.h b/tinySAK/src/tsk_runnable.h
new file mode 100644
index 0000000..d182dcd
--- /dev/null
+++ b/tinySAK/src/tsk_runnable.h
@@ -0,0 +1,167 @@
+/*
+* Copyright (C) 2009-2010 Mamadou Diop.
+*
+* Contact: Mamadou Diop <diopmamadou(at)doubango.org>
+*
+* This file is part of Open Source Doubango Framework.
+*
+* DOUBANGO is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* DOUBANGO is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with DOUBANGO.
+*
+*/
+
+/**@file tsk_runnable.h
+ * @brief Base class for runnable object.
+ *
+ * @author Mamadou Diop <diopmamadou(at)doubango.org>
+ *
+ * @date Created: Sat Nov 8 16:54:58 2009 mdiop
+ */
+#ifndef _TINYSAK_RUNNABLE_H_
+#define _TINYSAK_RUNNABLE_H_
+
+#include "tinysak_config.h"
+
+#include "tsk_object.h"
+#include "tsk_semaphore.h"
+#include "tsk_list.h"
+
+TSK_BEGIN_DECLS
+
+/**@ingroup tsk_runnable_group
+*/
+typedef void * (*tsk_runnable_func_run)(void* self);
+
+/**@ingroup tsk_runnable_group
+*/
+#define TSK_RUNNABLE(self) ((tsk_runnable_t*)(self))
+
+/**@ingroup tsk_runnable_group
+* Runnable.
+*/
+typedef struct tsk_runnable_s
+{
+ TSK_DECLARE_OBJECT;
+
+ const tsk_object_def_t *objdef;
+
+ void* tid[1];
+ tsk_runnable_func_run run;
+ tsk_semaphore_handle_t *semaphore;
+
+ tsk_bool_t running;
+ tsk_bool_t started;
+ tsk_bool_t initialized;
+ /** whether the enqueued data are important or not.
+ * if yes, the thread will not be joined until all data in the queue have been consumed.
+ * default value: tsk_false
+ */
+ tsk_bool_t important;
+
+ tsk_list_t *objects;
+}
+tsk_runnable_t;
+
+/**@ingroup tsk_runnable_group
+*/
+#define TSK_DECLARE_RUNNABLE tsk_runnable_t __runnable__
+
+TINYSAK_API tsk_runnable_t* tsk_runnable_create();
+
+TINYSAK_API int tsk_runnable_start(tsk_runnable_t *self, const tsk_object_def_t *objdef);
+TINYSAK_API int tsk_runnable_set_important(tsk_runnable_t *self, tsk_bool_t important);
+TINYSAK_API int tsk_runnable_enqueue(tsk_runnable_t *self, ...);
+TINYSAK_API int tsk_runnable_stop(tsk_runnable_t *self);
+
+TINYSAK_GEXTERN const tsk_object_def_t *tsk_runnable_def_t;
+
+
+/**@ingroup tsk_runnable_group
+* @def TSK_RUNNABLE_RUN_BEGIN
+*/
+/**@ingroup tsk_runnable_group
+* @def TSK_RUNNABLE_RUN_END
+*/
+#define TSK_RUNNABLE_RUN_BEGIN(self) \
+ TSK_RUNNABLE(self)->running = tsk_true; \
+ for(;;) { \
+ tsk_semaphore_decrement(TSK_RUNNABLE(self)->semaphore); \
+ if(!TSK_RUNNABLE(self)->running && \
+ (!TSK_RUNNABLE(self)->important || (TSK_RUNNABLE(self)->important && TSK_LIST_IS_EMPTY(TSK_RUNNABLE(self)->objects)))) \
+ break;
+
+
+#define TSK_RUNNABLE_RUN_END(self) \
+ } \
+ TSK_RUNNABLE(self)->running = tsk_false;
+
+/**@ingroup tsk_runnable_group
+* @def TSK_RUNNABLE_ENQUEUE
+*/
+/**@ingroup tsk_runnable_group
+* @def TSK_RUNNABLE_ENQUEUE_OBJECT
+*/
+#define TSK_RUNNABLE_ENQUEUE(self, ...) \
+{ \
+ if((self) && TSK_RUNNABLE(self)->initialized){ \
+ tsk_object_t *object = tsk_object_new(TSK_RUNNABLE(self)->objdef, ##__VA_ARGS__); \
+ tsk_list_push_back_data(TSK_RUNNABLE(self)->objects, (void**)&object); \
+ tsk_semaphore_increment(TSK_RUNNABLE(self)->semaphore); \
+ } \
+ else{ \
+ TSK_DEBUG_WARN("Invalid/uninitialized runnable object."); \
+ } \
+}
+
+#define TSK_RUNNABLE_ENQUEUE_OBJECT(self, object) \
+{ \
+ if((self) && TSK_RUNNABLE(self)->initialized){ \
+ tsk_list_push_back_data(TSK_RUNNABLE(self)->objects, (void**)&object); \
+ tsk_semaphore_increment(TSK_RUNNABLE(self)->semaphore); \
+ } \
+ else{ \
+ TSK_DEBUG_WARN("Invalid/uninitialized runnable object."); \
+ TSK_OBJECT_SAFE_FREE(object); \
+ } \
+}
+
+#define TSK_RUNNABLE_ENQUEUE_OBJECT_SAFE(self, object) \
+{ \
+ if((self) && TSK_RUNNABLE(self)->initialized){ \
+ tsk_list_lock(TSK_RUNNABLE(self)->objects); \
+ tsk_list_push_back_data(TSK_RUNNABLE(self)->objects, (void**)&object); \
+ tsk_list_unlock(TSK_RUNNABLE(self)->objects); \
+ tsk_semaphore_increment(TSK_RUNNABLE(self)->semaphore); \
+ } \
+ else{ \
+ TSK_DEBUG_WARN("Invalid/uninitialized runnable object."); \
+ TSK_OBJECT_SAFE_FREE(object); \
+ } \
+}
+
+/**@ingroup tsk_runnable_group
+*/
+#define TSK_RUNNABLE_POP_FIRST(self) \
+ tsk_list_pop_first_item(TSK_RUNNABLE(self)->objects)
+static tsk_list_item_t* TSK_RUNNABLE_POP_FIRST_SAFE(tsk_runnable_t* self){
+ tsk_list_item_t* item;
+ tsk_list_lock(self->objects);
+ item= tsk_list_pop_first_item(self->objects);
+ tsk_list_unlock(self->objects);
+ return item;
+}
+
+TSK_END_DECLS
+
+#endif /* _TINYSAK_RUNNABLE_H_ */
+
OpenPOWER on IntegriCloud