Files
blackbird/lci/extra/phs/src/Th.cj
T
2026-08-02 20:15:07 +08:00

313 lines
6.8 KiB
Plaintext

package phs
import std.sync.*;
/*
* Status 状态
*
* FIXME: 在枚举中定义操作函数
*/
enum Stat {
SHUT | STOP | START | RUNNING
}
/*
* Finite Status Machine 有限状态机
*
*
* FIXME(TritiumQin): 1. 柯里化
*
* FIXME(qing): 支持自定义状态
*/
open class Fsm {
/* 状态枚举 */
private var stat: Stat = STOP
/* 线程安全 */
private let mtx: Mutex = Mutex()
/*
* 条件变量
*
* FIXME: 我不知道这么写意义何在
*/
private let condition: Condition = synchronized(mtx) {
mtx.condition()
}
/* 辅助条件变量的布尔标志 */
private var flag: Bool = true
/* ---------------------------------------------- */
/*
* 阻塞等待状态改变,可以传入一个谓词,以确定什么时候终止
*
* 在该回调函数中返回true,则等待不会停止
*/
public func wait(keep!: (Stat) -> Bool = {_ => false}) {
synchronized(mtx) {
flag = true
while(flag || keep(stat)) {
condition.wait()
}
}
}
/* ---------------------------------------------- */
/*
* 对状态机进行某种操作,输入一个谓词。
*
* 会激活堵塞线程
*/
public func doc(p: (Stat) -> Stat): Stat {
synchronized(mtx) {
stat = p(stat)
flag= false // 试图唤醒阻塞的线程
condition.notifyAll()
return stat
}
}
/*
* 对状态机进行某种操作,输入一个谓词。
*
* 不会激活堵塞线程
*/
public func dop(p: (Stat) -> Stat): Stat {
synchronized(mtx) {
stat = p(stat)
return stat
}
}
}
/* Controllable Thread 可控制线程
*
* FIXME(花间岛):
* 1. 使用async语法糖
* 2. 封装iocp
*/
open class Th {
/* 持有线程类型 */
private var fut: Option<Future<Int64>> = None
/* 持有状态机类型 */
private let fsm: Fsm = Fsm()
/*----------------------------------------------*/
/* 持有静止事件回调 */
private var StopEvent: Option<() -> Unit> = None
/* 持有唤醒事件回调 */
private var WakeEvent: Option<() -> Unit> = None
/* 持有循环事件回调 */
private var LoopEvent: Option<() -> Unit> = None
/* 持有清理事件回调 */
private var ClearEvent: Option<() -> Unit> = None
/* 持有线程主函数回调 */
private var Main: Option<() -> Int64> = None // 线程主函数
/*----------------------------------------------*/
/* 使用谓词检查线程状态 */
public func chkp(): Stat {
return fsm.dop({ stat => return stat })
}
/*----------------------------------------------*/
/* 进入关闭状态 */
public func shut() {
fsm.doc({ _ => return SHUT })
}
/* 进入静止态 */
public func stop() {
fsm.doc({ _ => return STOP })
}
/* 进入启动状态 */
public func start() {
fsm.doc({ _ => return START })
}
/* 进入运行态 */
public func run() {
fsm.doc({ _ => return RUNNING })
}
/*----------------------------------------------*/
/* 状态机是否处于静止态 */
public func isStop() {
return match( chkp() ) {
case STOP => true
case _ => false
}}
/* 状态机是否处于关闭态 */
public func isShut() {
return match( chkp() ) {
case SHUT => true
case _ => false
}}
/* 状态机是否处于开始状态 */
public func isStart() {
return match( chkp() ) {
case START => true
case _ => false
}}
/* 状态机是否处于运行态 */
public func isRunning() {
return match( chkp() ) {
case RUNNING => true
case _ => false
}}
/*----------------------------------------------*/
/* 扮演函数,即设置线程事件 */
public func Act(
/* 静止事件 */
stop!: Option<() -> Unit> = None,
/* 唤醒事件 */
wake!: Option<() -> Unit> = None,
/* 循环事件 */
loop!: Option<() -> Unit> = None,
/* 清理事件 */
clear!:Option<() -> Unit> = None,
/* 线程主函数 */
mainloop!: Option<() -> Int64>= None
)
{
/* 只有静止态才能进行设置 */
if (!isStop()) { return; }
/* ------------------------------------------------- */
/* 设置静止事件,确保退出了静止态 */
StopEvent = stop ?? {=> fsm.wait(keep: {stat =>
match(stat) {
case STOP => true /* 保持等待 */
case _ => false
}
})}
/* 唤醒事件,默认直接进入运行态 */
WakeEvent = wake ?? {=> this.run()}
/* 循环事件,默认进行延时 */
LoopEvent = loop ?? {=> sleep(100 * Duration.millisecond)}
/* 清理事件,默认什么都不做 */
ClearEvent= clear?? {=> ;}
/* ------------------------------------------------- */
/* 线程主函数 */
Main = mainloop ?? {=>
/* 回字形循环 外层 */
while (!isShut()) {
this.inner()
}
return 0
}
/* ------------------------------------------------- */
}
/* ------------- 回字形循环 内层 -------------- */
private func inner() {
/* 静止状态 */
while(isStop()) { StopEvent.getOrThrow()() }
/* 唤醒事件 */
if (isStart()) { WakeEvent.getOrThrow()() }
/* 运行状态 */
while(isRunning()) { LoopEvent.getOrThrow()() }
/* 清理事件 */
ClearEvent.getOrThrow()()
}
/* --------------------------------------------- */
/*
* 创建资源,可控线程苏醒
*
* 如果在调用中等待线程启动,可能会造成死锁
* 想了想觉得也没有这个必要
*/
public func wake() {
/* 存在微小的冲突可能,所以我不让它进入静止态 */
this.start()
/* 创建卵 */
fut = Some<Future<Int64>>(spawn {
Main.getOrThrow()()
})
/* 等启动
*
* 20251020(qing): 如果线程启动太快,该等待可能会导致死锁
*/
//fsm.wait(keep: {stat => match(stat) {
// case START => true
// case _ => false
//}})
}
/* 等待线程结束 */
public func wait() {
let f = fut.getOrThrow()
return f.get()
}
/*
* 关闭线程,然后等待线程结束
*/
public func shut_and_wait() {
shut()
wait()
}
}