Skip to main content

atmos/os_lib/
worker.rs

1//! WHATWG HTML Living Standard § 10 準拠の Web Workers コアロジック
2//!
3//! `Worker`、`DedicatedWorkerGlobalScope` のライフサイクル状態機械、
4//! メッセージキュー、双方向メッセージパッシング(メイン ⇄ ワーカー)の純粋抽象を提供する。
5//! ハードウェア依存のない純粋ロジックであり、ホストテスト環境でも高速・安全に検証可能。
6
7extern crate alloc;
8
9use alloc::collections::VecDeque;
10use alloc::string::String;
11
12/// ワーカーの動作状態
13#[derive(Debug, Clone, Copy, PartialEq, Eq)]
14pub enum WorkerState {
15    /// 実行可能 / 稼働中
16    Running,
17    /// 終了済み(terminate() または close() 呼び出し後)
18    Terminated,
19}
20
21/// ワーカーメッセージ送受信エラー
22#[derive(Debug, Clone, PartialEq, Eq)]
23pub enum WorkerError {
24    /// 既に終了したワーカーに対する操作
25    AlreadyTerminated,
26    /// キューが空
27    QueueEmpty,
28}
29
30/// Web Worker の純粋状態・メッセージキュー管理コア
31#[derive(Debug, Clone)]
32pub struct WorkerCore {
33    pub id: usize,
34    pub script_url: String,
35    pub state: WorkerState,
36    pub to_worker_queue: VecDeque<String>,
37    pub to_main_queue: VecDeque<String>,
38}
39
40impl WorkerCore {
41    /// 新規 Worker コアの生成
42    pub fn new(id: usize, script_url: &str) -> Self {
43        Self {
44            id,
45            script_url: String::from(script_url),
46            state: WorkerState::Running,
47            to_worker_queue: VecDeque::new(),
48            to_main_queue: VecDeque::new(),
49        }
50    }
51
52    /// ワーカーが稼働中か
53    pub fn is_running(&self) -> bool {
54        self.state == WorkerState::Running
55    }
56
57    /// メインスレッドからワーカーへメッセージを送信 (worker.postMessage)
58    pub fn post_to_worker(&mut self, message: &str) -> Result<(), WorkerError> {
59        if self.state == WorkerState::Terminated {
60            return Err(WorkerError::AlreadyTerminated);
61        }
62        self.to_worker_queue.push_back(String::from(message));
63        Ok(())
64    }
65
66    /// ワーカーからメインスレッドへメッセージを送信 (self.postMessage)
67    pub fn post_to_main(&mut self, message: &str) -> Result<(), WorkerError> {
68        if self.state == WorkerState::Terminated {
69            return Err(WorkerError::AlreadyTerminated);
70        }
71        self.to_main_queue.push_back(String::from(message));
72        Ok(())
73    }
74
75    /// ワーカー宛のメッセージを取り出し
76    pub fn pop_worker_message(&mut self) -> Option<String> {
77        if self.state == WorkerState::Terminated {
78            return None;
79        }
80        self.to_worker_queue.pop_front()
81    }
82
83    /// メインスレッド宛のメッセージを取り出し
84    pub fn pop_main_message(&mut self) -> Option<String> {
85        if self.state == WorkerState::Terminated {
86            return None;
87        }
88        self.to_main_queue.pop_front()
89    }
90
91    /// ワーカーを終了 (worker.terminate() または self.close())
92    pub fn terminate(&mut self) {
93        self.state = WorkerState::Terminated;
94        self.to_worker_queue.clear();
95        self.to_main_queue.clear();
96    }
97}