fix: Add interrupt protection to TTY operations to prevent deadlock
All checks were successful
ParrotXray/CureOS/pipeline/head This commit looks good

This commit is contained in:
ParrotXray 2025-11-17 19:16:25 +08:00
parent 018dd0c28c
commit dc120daa5a
Signed by: ParrotXray
SSH Key Fingerprint: SHA256:OEnKoo72UOfrmZ3LVSBn9K/UfpEzNrl+q8JMLG9CaAI
3 changed files with 63 additions and 37 deletions

58
Jenkinsfile vendored
View File

@ -11,30 +11,40 @@ properties([
node('ccis') {
stage('Setup Environment') {
cleanWs()
checkout scm
def image = docker.build('cureos-builder', '.')
env.IMAGE_ID = image.id
}
stage('Build with Make') {
docker.image(env.IMAGE_ID).inside("--user jenkins") {
sh '''
echo "=== Environment Check ==="
rustc --version
cargo --version
make --version
echo ""
echo "=== Building with Make ==="
make all
'''
try{
stage('Setup Environment') {
cleanWs()
checkout scm
def image = docker.build('cureos-builder', '.')
env.IMAGE_ID = image.id
}
}
stage('Archive') {
archiveArtifacts artifacts: 'build/**/*.img, bin/**/*',
fingerprint: true
stage('Build with Make') {
docker.image(env.IMAGE_ID).inside("--user jenkins") {
sh '''
echo "=== Environment Check ==="
rustc --version
cargo --version
make --version
echo ""
echo "=== Building with Make ==="
make all
'''
}
}
stage('Archive') {
archiveArtifacts artifacts: 'build/**/*.img, bin/**/*',
fingerprint: true
}
} finally {
stage('Cleanup') {
sh """
docker ps -a --filter "label=jenkins-build=${JOB_NAME}" -q | xargs -r docker rm -f || true
docker rmi ${env.IMAGE_ID} || true
"""
}
}
}

View File

@ -1,5 +1,6 @@
// kernel/src/tty/device
use alloc::{collections::VecDeque, vec::Vec};
use x86_64::instructions::interrupts;
use spin::Mutex;
use crate::{kprint, process};
@ -111,20 +112,20 @@ impl Device {
}
}
// 全局 TTY 設備
static TTY0: Mutex<Device> = Mutex::new(Device::new());
/// 接收字符(給鍵盤驅動調用)
pub fn receive_char(c: u8) {
TTY0.lock().receive_char(c);
}
/// 讀取一行(給進程調用)
pub fn read_line(pid: u64) -> Option<Vec<u8>> {
TTY0.lock().read_line(pid)
interrupts::without_interrupts(|| {
TTY0.lock().read_line(pid)
})
}
/// 檢查是否有數據
pub fn has_input() -> bool {
TTY0.lock().has_line()
interrupts::without_interrupts(|| {
TTY0.lock().has_line()
})
}

View File

@ -1,4 +1,5 @@
use bootloader_api::info::{FrameBuffer, FrameBufferInfo, PixelFormat};
use x86_64::instructions::interrupts;
use crate::tty::font::FONT_BASIC;
use spin::Mutex;
@ -214,23 +215,33 @@ pub fn init(framebuffer: &'static mut FrameBuffer) {
let info = framebuffer.info();
let buffer = framebuffer.buffer_mut();
TTY.lock().init(buffer.as_mut_ptr(), buffer.len(), info);
interrupts::without_interrupts(|| {
TTY.lock().init(buffer.as_mut_ptr(), buffer.len(), info);
});
}
pub fn clear(color: u32) {
TTY.lock().clear(color);
interrupts::without_interrupts(|| {
TTY.lock().clear(color);
});
}
pub fn draw_pixel(x: usize, y: usize, color: u32) {
TTY.lock().draw_pixel(x, y, color);
interrupts::without_interrupts(|| {
TTY.lock().draw_pixel(x, y, color);
});
}
pub fn draw_char(c: char, color: u32) {
TTY.lock().draw_char(c, color);
interrupts::without_interrupts(|| {
TTY.lock().draw_char(c, color);
});
}
pub fn write_str(s: &str, color: u32) {
TTY.lock().write_str(s, color);
interrupts::without_interrupts(|| {
TTY.lock().write_str(s, color);
});
}
pub fn tty_put_str(s: &str, color: Option<u32>) {
@ -239,11 +250,15 @@ pub fn tty_put_str(s: &str, color: Option<u32>) {
}
pub fn get_cursor_pos() -> (usize, usize) {
TTY.lock().get_cursor_pos()
interrupts::without_interrupts(|| {
TTY.lock().get_cursor_pos()
})
}
pub fn set_cursor_pos(x: usize, y: usize) {
TTY.lock().set_cursor_pos(x, y);
interrupts::without_interrupts(|| {
TTY.lock().set_cursor_pos(x, y);
});
}
fn write_pixel(info: &FrameBufferInfo, pixel: &mut [u8], r: u8, g: u8, b: u8) {