diff --git a/stdlib/src/sync.rs b/stdlib/src/sync.rs index 36ec88f4..7028188a 100644 --- a/stdlib/src/sync.rs +++ b/stdlib/src/sync.rs @@ -34,74 +34,75 @@ impl ScriptMutex { } } +fn make_mutex_fn() -> Rc { + Rc::new(StdFunction { + name: "make_mutex".to_string(), + arity: 0, + callback: |ctx, _args| { + let mutex = ScriptMutex::new(); + let handle_id = ctx.resources.borrow_mut().insert(mutex); + let mut map = IndexMap::new(); + map.insert("_handle".to_string(), RuntimeValue::Int(handle_id as i64)); + Ok(RuntimeValue::Map { + entries: Rc::new(RefCell::new(map)), + is_const: false, + }) + }, + }) +} + +fn mutex_lock_fn() -> Rc { + Rc::new(StdFunction { + name: "mutex_lock".to_string(), + arity: 1, + callback: |ctx, args| { + if let RuntimeValue::Map { entries, .. } = &args[0] { + let handle_id = entries + .borrow() + .get("_handle") + .cloned() + .unwrap_or(RuntimeValue::Null) + .try_into_int()? as u32; + let resources = ctx.resources.borrow(); + if let Some(mutex) = resources.get::(handle_id) { + mutex.lock(); + } + } + Ok(RuntimeValue::Null) + }, + }) +} + +fn mutex_unlock_fn() -> Rc { + Rc::new(StdFunction { + name: "mutex_unlock".to_string(), + arity: 1, + callback: |ctx, args| { + if let RuntimeValue::Map { entries, .. } = &args[0] { + let handle_id = entries + .borrow() + .get("_handle") + .cloned() + .unwrap_or(RuntimeValue::Null) + .try_into_int()? as u32; + let resources = ctx.resources.borrow(); + if let Some(mutex) = resources.get::(handle_id) { + mutex.unlock(); + } + } + Ok(RuntimeValue::Null) + }, + }) +} + impl StdlibRegistry { pub fn register_sync(&mut self) { let mut exports: HashMap> = HashMap::new(); - exports.insert( - "make_mutex".to_string(), - Rc::new(StdFunction { - name: "make_mutex".to_string(), - arity: 0, - callback: |ctx, _args| { - let mutex = ScriptMutex::new(); - let handle_id = ctx.resources.borrow_mut().insert(mutex); - let mut map = IndexMap::new(); - map.insert("_handle".to_string(), RuntimeValue::Int(handle_id as i64)); - Ok(RuntimeValue::Map { - entries: Rc::new(RefCell::new(map)), - is_const: false, - }) - }, - }), - ); - - exports.insert( - "mutex_lock".to_string(), - Rc::new(StdFunction { - name: "mutex_lock".to_string(), - arity: 1, - callback: |ctx, args| { - if let RuntimeValue::Map { entries, .. } = &args[0] { - let handle_id = entries - .borrow() - .get("_handle") - .cloned() - .unwrap_or(RuntimeValue::Null) - .try_into_int()? as u32; - let resources = ctx.resources.borrow(); - if let Some(mutex) = resources.get::(handle_id) { - mutex.lock(); - } - } - Ok(RuntimeValue::Null) - }, - }), - ); - - exports.insert( - "mutex_unlock".to_string(), - Rc::new(StdFunction { - name: "mutex_unlock".to_string(), - arity: 1, - callback: |ctx, args| { - if let RuntimeValue::Map { entries, .. } = &args[0] { - let handle_id = entries - .borrow() - .get("_handle") - .cloned() - .unwrap_or(RuntimeValue::Null) - .try_into_int()? as u32; - let resources = ctx.resources.borrow(); - if let Some(mutex) = resources.get::(handle_id) { - mutex.unlock(); - } - } - Ok(RuntimeValue::Null) - }, - }), - ); + exports.insert("make_mutex".to_string(), make_mutex_fn()); + exports.insert("mutex_lock".to_string(), mutex_lock_fn()); + exports.insert("mutex_unlock".to_string(), mutex_unlock_fn()); self.register_module( "std.sync",