33#include " ../dmdism/disassembly.h"
44#include " ../dmdism/opcodes.h"
55
6+ #include < condition_variable>
7+ #include < mutex>
8+
69typedef const char * (byond_ffi_func)(int , const char **);
710
811std::map<float , SuspendedProc*> suspended_procs;
@@ -12,14 +15,19 @@ std::uint32_t result_string_id = 0;
1215std::uint32_t completed_string_id = 0 ;
1316std::uint32_t internal_id_string_id = 0 ;
1417
18+ std::condition_variable unsuspend_ready_cv;
19+ std::mutex unsuspend_ready_mutex;
20+
1521void tffi_suspend (ExecutionContext* ctx)
1622{
1723 ctx->current_opcode ++;
1824 SuspendedProc* proc = Suspend (ctx, 0 );
1925 proc->time_to_resume = 0x7FFFFF ;
2026 StartTiming (proc);
2127 float promise_id = ctx->constants ->args [1 ].valuef ;
28+ std::lock_guard<std::mutex> lk (unsuspend_ready_mutex);
2229 suspended_procs[promise_id] = proc;
30+ unsuspend_ready_cv.notify_all ();
2331 ctx->current_opcode --;
2432}
2533
@@ -48,19 +56,8 @@ void ffi_thread(byond_ffi_func* proc, int promise_id, int n_args, std::vector<st
4856 SetVariable ( 0x21 , promise_id , result_string_id, { 0x06 , (int )Core::GetString (res) });
4957 SetVariable ( 0x21 , promise_id , completed_string_id, { 0x2A , 1 });
5058 float internal_id = GetVariable ( 0x21 , promise_id , internal_id_string_id).valuef ;
51- while (true )
52- {
53- if (suspended_procs.find (internal_id) != suspended_procs.end ())
54- {
55- break ;
56- }
57- #ifdef _WIN32
58- Sleep (1 );
59- #else
60- usleep (1000 );
61- #endif
62- // TODO: some kind of conditional variable or WaitForObject?
63- }
59+ std::unique_lock<std::mutex> lk (unsuspend_ready_mutex);
60+ unsuspend_ready_cv.wait (lk, [internal_id] { return suspended_procs.find (internal_id) != suspended_procs.end (); });
6461 suspended_procs[internal_id]->time_to_resume = 1 ;
6562 suspended_procs.erase (internal_id);
6663}
0 commit comments