vxx2 / vlib / x / executor / sync_call.v
44 lines · 41 sloc · 1.08 KB · e80386b6af8a071a2e13fd654ebcdb2105fb9202
Raw
1module executor
2
3import context
4import sync
5
6// run_sync runs f on the owner thread and waits until it finishes.
7//
8// Calls from the active owner pump execute inline, outside executor mutexes, to
9// avoid deadlock. Inline calls still require open admission; an inline error is
10// stored as the executor's first job error even if the outer callback catches it.
11// That inline execution is outside FIFO queue ordering.
12pub fn (mut e Executor) run_sync(f JobFn) ! {
13 if f == unsafe { nil } {
14 return error(err_nil_job)
15 }
16 thread_id := sync.thread_id()
17 e.mutex.lock()
18 is_owner := e.owner_active && e.owner_thread_id == thread_id
19 accepting := e.accepting
20 e.mutex.unlock()
21 if is_owner {
22 if !accepting {
23 return error(err_executor_closed)
24 }
25 f() or {
26 e.set_first_error(err)
27 return err
28 }
29 return
30 }
31
32 result_ch := chan ExecutorJobResult{cap: 1}
33 job := ExecutorJob{
34 f: f
35 result_ch: result_ch
36 has_result: true
37 report_error: true
38 }
39 e.enqueue_job_with_context(context.background(), job)!
40 result := <-result_ch
41 if result.err !is none {
42 return result.err
43 }
44}
45