28 static void* MICROEJ_ASYNC_WORKER_loop(
void* args);
35 int32_t job_count = async_worker->job_count;
37 || async_worker->waiting_threads_length <= 1
39 return MICROEJ_ASYNC_WORKER_INVALID_ARGS;
44 void* params = async_worker->params;
45 int32_t params_sizeof = async_worker->params_sizeof;
46 for(
int i=0 ; i<job_count-1 ; i++){
47 jobs[i].
_intern.next_free_job = &jobs[i+1];
49 params = (
void *) ( (int32_t)params + params_sizeof );
51 jobs[job_count-1].
_intern.next_free_job = NULL;
52 jobs[job_count-1].
params = params;
55 OSAL_status_t res = OSAL_queue_create(name, async_worker->job_count, &async_worker->jobs_queue);
57 return MICROEJ_ASYNC_WORKER_ERROR;
61 res = OSAL_mutex_create(name, &async_worker->mutex);
63 return MICROEJ_ASYNC_WORKER_ERROR;
67 res = OSAL_task_create(MICROEJ_ASYNC_WORKER_loop, name, stack, priority, async_worker, &async_worker->task);
69 return MICROEJ_ASYNC_WORKER_ERROR;
72 return MICROEJ_ASYNC_WORKER_OK;
80 OSAL_mutex_take(&async_worker->mutex, OSAL_INFINITE_TIME);
82 job = async_worker->free_jobs;
85 async_worker->free_jobs = job->
_intern.next_free_job;
86 job->
_intern.next_free_job = NULL;
89 OSAL_mutex_give(&async_worker->mutex);
95 int32_t free_waiting_thread_offset = async_worker->free_waiting_thread_offset;
96 int32_t new_free_waiting_thread_offset = free_waiting_thread_offset + 1;
97 if(new_free_waiting_thread_offset >= async_worker->waiting_threads_length){
98 new_free_waiting_thread_offset = 0;
101 if(new_free_waiting_thread_offset == async_worker->waiting_thread_offset){
103 SNI_throwNativeIOException(-1,
"MICROEJ_ASYNC_WORKER: thread cannot be suspended, waiting list is full.");
106 async_worker->free_waiting_thread_offset = (uint16_t)new_free_waiting_thread_offset;
107 int32_t thread_id = SNI_getCurrentJavaThreadID();
108 async_worker->waiting_threads[free_waiting_thread_offset] = thread_id;
109 SNI_suspendCurrentJavaThreadWithCallback(0, (SNI_callback) sni_retry_callback, NULL);
118 OSAL_mutex_take(&async_worker->mutex, OSAL_INFINITE_TIME);
120 job->
_intern.next_free_job = async_worker->free_jobs;
121 async_worker->free_jobs = job;
123 int32_t waiting_thread_offset = async_worker->waiting_thread_offset;
124 if(waiting_thread_offset != async_worker->free_waiting_thread_offset){
126 int32_t thread_id = async_worker->waiting_threads[waiting_thread_offset];
127 int32_t new_waiting_thread_offset = waiting_thread_offset + 1;
128 if(new_waiting_thread_offset >= async_worker->waiting_threads_length){
129 new_waiting_thread_offset = 0;
131 async_worker->waiting_thread_offset = new_waiting_thread_offset;
132 SNI_resumeJavaThread(thread_id);
135 OSAL_mutex_give(&async_worker->mutex);
137 return MICROEJ_ASYNC_WORKER_OK;
141 return MICROEJ_ASYNC_WORKER_async_exec_intern(async_worker, job, action, on_done_callback,
true);
145 return MICROEJ_ASYNC_WORKER_async_exec_intern(async_worker, job, action, NULL,
false);
152 job->
_intern.thread_id = SNI_getCurrentJavaThreadID();
155 job->
_intern.thread_id = SNI_ERROR;
158 OSAL_status_t res = OSAL_queue_post(&async_worker->jobs_queue, job);
161 SNI_suspendCurrentJavaThreadWithCallback(0, (SNI_callback)on_done_callback, job);
163 return MICROEJ_ASYNC_WORKER_OK;
166 SNI_throwNativeIOException(-1,
"MICROEJ_ASYNC_WORKER: Internal error.");
167 return MICROEJ_ASYNC_WORKER_ERROR;
174 SNI_getCallbackArgs((
void**)&job, NULL);
178 static void* MICROEJ_ASYNC_WORKER_loop(
void* args){
183 OSAL_status_t res = OSAL_queue_fetch(&async_worker->jobs_queue, (
void**)&job, OSAL_INFINITE_TIME);
188 if(job->
_intern.thread_id != SNI_ERROR){
189 SNI_resumeJavaThread(job->
_intern.thread_id);
Asynchronous Worker API. This library helps writing SNI functions that must be executed asynchronousl...
MICROEJ_ASYNC_WORKER_status_t MICROEJ_ASYNC_WORKER_async_exec(MICROEJ_ASYNC_WORKER_handle_t *async_worker, MICROEJ_ASYNC_WORKER_job_t *job, MICROEJ_ASYNC_WORKER_action_t action, SNI_callback on_done_callback)
Executes the given job asynchronously.
void(* MICROEJ_ASYNC_WORKER_action_t)(MICROEJ_ASYNC_WORKER_job_t *job)
Pointer to a function to call asynchronously.
MICROEJ_ASYNC_WORKER_status_t MICROEJ_ASYNC_WORKER_free_job(MICROEJ_ASYNC_WORKER_handle_t *async_worker, MICROEJ_ASYNC_WORKER_job_t *job)
Frees a job previously allocated with MICROEJ_ASYNC_WORKER_allocate_job().
void * params
Pointers to the parameters.
A job to execute in a worker.
MICROEJ_ASYNC_WORKER_job_t * MICROEJ_ASYNC_WORKER_allocate_job(MICROEJ_ASYNC_WORKER_handle_t *async_worker, SNI_callback sni_retry_callback)
Allocates a new job for the given worker.
MICROEJ_ASYNC_WORKER_status_t
Return codes list.
struct MICROEJ_ASYNC_WORKER_job::@0 _intern
Structure internal data. Must not be modified.
MICROEJ_ASYNC_WORKER_status_t MICROEJ_ASYNC_WORKER_async_exec_no_wait(MICROEJ_ASYNC_WORKER_handle_t *async_worker, MICROEJ_ASYNC_WORKER_job_t *job, MICROEJ_ASYNC_WORKER_action_t action)
Executes the given job asynchronously.
MICROEJ_ASYNC_WORKER_status_t MICROEJ_ASYNC_WORKER_initialize(MICROEJ_ASYNC_WORKER_handle_t *async_worker, uint8_t *name, OSAL_task_stack_t stack, int32_t priority)
Initializes and starts a worker previously declared with MICROEJ_ASYNC_WORKER_worker_declare() macro...
MICROEJ_ASYNC_WORKER_job_t * MICROEJ_ASYNC_WORKER_get_job_done(void)
Returns the job that has been executed.