int _zbar_thread_start (zbar_thread_t *thr, zbar_thread_proc_t *proc, void *arg, zbar_mutex_t *lock) { HANDLE hthr; int rc; if(thr->started || thr->running) return(-1/*FIXME*/); thr->started = 1; _zbar_event_init(&thr->notify); _zbar_event_init(&thr->activity); hthr = CreateThread(NULL, 0, proc, arg, 0, NULL); rc = (!hthr || _zbar_event_wait(&thr->activity, NULL, NULL) < 0 || !thr->running); CloseHandle(hthr); if(rc) { thr->started = 0; _zbar_event_destroy(&thr->notify); _zbar_event_destroy(&thr->activity); return(-1/*FIXME*/); } return(0); }
int _zbar_processor_wait (zbar_processor_t *proc, unsigned events, zbar_timer_t *timeout) { _zbar_mutex_lock(&proc->mutex); int save_level = proc->lock_level; proc_waiter_t *waiter = proc_waiter_queue(proc); waiter->events = events & EVENTS_PENDING; _zbar_processor_unlock(proc, 1); int rc; if(proc->threaded) rc = _zbar_event_wait(&waiter->notify, &proc->mutex, timeout); else rc = proc_wait_unthreaded(proc, waiter, timeout); if(rc <= 0 || !proc->threaded) { /* reacquire api lock */ waiter->events &= EVENT_CANCELED; proc->wait_next = NULL; if(!proc->lock_level) { proc_waiter_t *w = proc_waiter_dequeue(proc); assert(w == waiter); } else _zbar_event_wait(&waiter->notify, &proc->mutex, NULL); } if(rc > 0 && (waiter->events & EVENT_CANCELED)) rc = -1; assert(proc->lock_level == 1); assert(_zbar_thread_is_self(proc->lock_owner)); proc->lock_level = save_level; proc_waiter_release(proc, waiter); _zbar_mutex_unlock(&proc->mutex); return(rc); }
int _zbar_thread_stop (zbar_thread_t *thr, zbar_mutex_t *lock) { if(thr->started) { thr->started = 0; _zbar_event_trigger(&thr->notify); while(thr->running) /* FIXME time out and abandon? */ _zbar_event_wait(&thr->activity, lock, NULL); _zbar_event_destroy(&thr->notify); _zbar_event_destroy(&thr->activity); } return(0); }
static ZTHREAD proc_video_thread (void *arg) { zbar_processor_t *proc = arg; zbar_thread_t *thread = &proc->video_thread; _zbar_mutex_lock(&proc->mutex); _zbar_thread_init(thread); zprintf(4, "spawned video thread\n"); while(thread->started) { /* wait for video stream to be active */ while(thread->started && !proc->streaming) _zbar_event_wait(&thread->notify, &proc->mutex, NULL); if(!thread->started) break; /* blocking capture image from video */ _zbar_mutex_unlock(&proc->mutex); zbar_image_t *img = zbar_video_next_image(proc->video); _zbar_mutex_lock(&proc->mutex); if(!img && !proc->streaming) continue; else if(!img) /* FIXME could abort streaming and keep running? */ break; /* acquire API lock */ _zbar_processor_lock(proc); _zbar_mutex_unlock(&proc->mutex); if(thread->started && proc->streaming) _zbar_process_image(proc, img); zbar_image_destroy(img); _zbar_mutex_lock(&proc->mutex); /* release API lock */ _zbar_processor_unlock(proc, 0); } thread->running = 0; _zbar_event_trigger(&thread->activity); _zbar_mutex_unlock(&proc->mutex); return(0); }
int _zbar_processor_lock (zbar_processor_t *proc) { if(!proc->lock_level) { proc->lock_owner = _zbar_thread_self(); proc->lock_level = 1; return(0); } if(_zbar_thread_is_self(proc->lock_owner)) { proc->lock_level++; return(0); } proc_waiter_t *waiter = proc_waiter_queue(proc); _zbar_event_wait(&waiter->notify, &proc->mutex, NULL); assert(proc->lock_level == 1); assert(_zbar_thread_is_self(proc->lock_owner)); proc_waiter_release(proc, waiter); return(0); }