diff options
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | apps/wm/main.c | 34 | ||||
-rw-r--r-- | kernel/features/bus.c | 42 | ||||
-rw-r--r-- | kernel/features/dev.c | 14 | ||||
-rw-r--r-- | kernel/features/proc.c | 2 | ||||
-rw-r--r-- | kernel/features/syscall.c | 7 | ||||
-rw-r--r-- | kernel/inc/dev.h | 1 | ||||
-rw-r--r-- | kernel/inc/proc.h | 2 | ||||
-rw-r--r-- | libs/libgui/msg.c | 5 |
9 files changed, 64 insertions, 45 deletions
@@ -9,7 +9,7 @@ endef PREPROCESSOR_FLAGS = $(foreach flag, $(ALL_PREPROCESSOR_FLAGS), $(call PREPROCESSOR_FLAG_TEMPLATE,$(flag))) -CFLAGS_WARNINGS = -Wall -Wextra -Werror -Wshadow -Wpointer-arith -Wwrite-strings -Wredundant-decls -Wnested-externs -Wformat=2 -Wmissing-declarations -Wstrict-prototypes -Wmissing-prototypes -Wcast-qual -Wswitch-default -Wswitch-enum -Wunreachable-code -Wundef -Wold-style-definition -Wvla -Winline -pedantic-errors +CFLAGS_WARNINGS = -Wall -Wextra -Werror -Wshadow -Wpointer-arith -Wwrite-strings -Wredundant-decls -Wnested-externs -Wformat=2 -Wmissing-declarations -Wstrict-prototypes -Wmissing-prototypes -Wcast-qual -Wswitch-default -Wswitch-enum -Wunreachable-code -Wundef -Wold-style-definition -Wvla -pedantic-errors CFLAGS_DEFAULT = $(CFLAGS_WARNINGS) -std=c99 -m32 -nostdlib -nostdinc -fno-builtin -fno-profile-generate -fno-omit-frame-pointer -fno-common -fno-asynchronous-unwind-tables -mno-red-zone -mno-mmx -mno-sse -mno-sse2 $(CONFIG_OPTIMIZATION) $(CONFIG_EXTRA_CFLAGS) $(PREPROCESSOR_FLAGS) CC = $(CONFIG_CACHE) $(PWD)/cross/opt/bin/i686-elf-gcc diff --git a/apps/wm/main.c b/apps/wm/main.c index 3f01922..6a4b9bf 100644 --- a/apps/wm/main.c +++ b/apps/wm/main.c @@ -596,6 +596,7 @@ static void handle_message_new_window(struct message_new_window *msg) struct window *win = window_new((struct client){ .conn = msg->header.bus.conn }, msg->pos, vec2_add(msg->size, vec2(0, BAR_HEIGHT)), WF_BAR); window_bar_draw(win, msg->name); + window_redraw(win); msg->ctx = win->ctx; msg->off = vec2(0, BAR_HEIGHT); @@ -753,8 +754,7 @@ int main(int argc, char **argv) assert(dev_control(DEV_BUS, DEVCTL_BUS_REGISTER, "wm") == EOK); - assert(exec("test", NULL) == EOK); - assert(exec("test", NULL) == EOK); + assert(exec("view", NULL) == EOK); u8 msg[1024] = { 0 }; struct event_keyboard event_keyboard = { 0 }; @@ -763,23 +763,21 @@ int main(int argc, char **argv) while (1) { res poll_ret = 0; - if ((poll_ret = dev_poll(listeners)) >= 0) { - if (poll_ret == DEV_KEYBOARD) { - if (dev_read(DEV_KEYBOARD, &event_keyboard, 0, - sizeof(event_keyboard)) > 0) - handle_event_keyboard(&event_keyboard); - } else if (poll_ret == DEV_MOUSE) { - if (dev_read(DEV_MOUSE, &event_mouse, 0, sizeof(event_mouse)) > 0) - handle_event_mouse(&event_mouse); - } else if (poll_ret == DEV_BUS) { - if (msg_receive(msg, sizeof(msg)) > 0) - handle_message(msg); - } - - window_ping_all(); - continue; + if ((poll_ret = dev_poll(listeners)) < 0) + panic("Poll/read error: %s\n", strerror(errno)); + + if (poll_ret == DEV_KEYBOARD) { + if (dev_read(DEV_KEYBOARD, &event_keyboard, 0, sizeof(event_keyboard)) > 0) + handle_event_keyboard(&event_keyboard); + } else if (poll_ret == DEV_MOUSE) { + if (dev_read(DEV_MOUSE, &event_mouse, 0, sizeof(event_mouse)) > 0) + handle_event_mouse(&event_mouse); + } else if (poll_ret == DEV_BUS) { + if (msg_receive(msg, sizeof(msg)) > 0) + handle_message(msg); } - panic("Poll/read error: %s\n", strerror(errno)); + + window_ping_all(); } return 1; diff --git a/kernel/features/bus.c b/kernel/features/bus.c index ad7352f..811ad88 100644 --- a/kernel/features/bus.c +++ b/kernel/features/bus.c @@ -93,6 +93,21 @@ static void bus_add_conn(u32 hash, u32 conn) list_add(bus_conns, bus_conn); } +static res bus_conn_ready(struct bus_conn *bus_conn) +{ + struct bus *bus = bus_find_bus(bus_conn->bus); + if (!bus) + return -ENOENT; + + u8 ready = 0; + if (bus->pid == proc_current()->pid) + ready = !stack_empty(bus_conn->in); + else + ready = !stack_empty(bus_conn->out); + + return ready ? EOK : -EAGAIN; +} + static res bus_register(const char *name) { if (!memory_readable(name)) @@ -236,14 +251,14 @@ static res bus_receive(void *buf, u32 offset, u32 count) struct node *iterator = bus_conns->head; while (iterator) { struct bus_conn *sub_bus = iterator->data; - if (sub_bus->bus == bus_owner->hash) + if (sub_bus->bus == bus_owner->hash && bus_conn_ready(sub_bus) == EOK) return bus_conn_receive(sub_bus, buf, offset, count); iterator = iterator->next; } } - if (bus_conn) + if (bus_conn && bus_conn_ready(bus_conn) == EOK) return bus_conn_receive(bus_conn, buf, offset, count); return -EAGAIN; @@ -286,21 +301,6 @@ static res bus_read(void *buf, u32 offset, u32 count) return bus_receive(buf, offset, count); } -static res bus_conn_ready(struct bus_conn *bus_conn) -{ - struct bus *bus = bus_find_bus(bus_conn->bus); - if (!bus) - return -ENOENT; - - u8 ready = 0; - if (bus->pid == proc_current()->pid) - ready = !stack_empty(bus_conn->in); - else - ready = !stack_empty(bus_conn->out); - - return ready ? EOK : -EAGAIN; -} - static res bus_ready(void) { struct bus *bus_owner = bus_find_owner(proc_current()->pid); @@ -312,15 +312,15 @@ static res bus_ready(void) struct node *iterator = bus_conns->head; while (iterator) { struct bus_conn *sub_bus = iterator->data; - if (sub_bus->bus == bus_owner->hash) - return bus_conn_ready(sub_bus); + if (sub_bus->bus == bus_owner->hash && bus_conn_ready(sub_bus) == EOK) + return EOK; iterator = iterator->next; } } - if (bus_conn) - return bus_conn_ready(bus_conn); + if (bus_conn && bus_conn_ready(bus_conn) == EOK) + return EOK; return -EAGAIN; } diff --git a/kernel/features/dev.c b/kernel/features/dev.c index ecc3f0c..0e082f9 100644 --- a/kernel/features/dev.c +++ b/kernel/features/dev.c @@ -63,6 +63,20 @@ static void dev_remove_group(u32 group) group_id--; } +void dev_remove_proc(struct proc *proc) +{ + for (u32 dev = DEV_MIN; dev < DEV_MAX; dev++) { + struct node *iterator = dev_listeners[dev]->head; + while (iterator) { + struct dev_listener *listener = iterator->data; + struct node *next = iterator->next; + if (listener->proc == proc) + list_remove(dev_listeners[dev], iterator); + iterator = next; + } + } +} + CLEAR void dev_add(enum dev_type type, struct dev_dev *dev) { assert(dev_type_valid(type) && !dev_mappings[type]); diff --git a/kernel/features/proc.c b/kernel/features/proc.c index 70e3666..03f45c9 100644 --- a/kernel/features/proc.c +++ b/kernel/features/proc.c @@ -1,6 +1,7 @@ // MIT License, Copyright (c) 2020 Marvin Borner #include <assert.h> +#include <dev.h> #include <drivers/cpu.h> #include <drivers/gdt.h> #include <drivers/timer.h> @@ -190,6 +191,7 @@ void proc_exit(s32 status) printf("Process didn't leak memory!\n"); } + dev_remove_proc(proc); stack_destroy(proc->messages); list_destroy(proc->memory); // TODO: Decrement memory ref links virtual_destroy_dir(proc->page_dir); diff --git a/kernel/features/syscall.c b/kernel/features/syscall.c index 997fa96..16a83d6 100644 --- a/kernel/features/syscall.c +++ b/kernel/features/syscall.c @@ -63,10 +63,11 @@ static u32 syscall_handler(u32 esp) break; } case SYS_DEV_READ: { - res ready = dev_ready(frame->ebx); - if (ready == -EAGAIN) { + // TODO: This could be done more elegant (e.g. with better bus design) + res ready; + while ((ready = dev_ready(frame->ebx)) == -EAGAIN) dev_block(frame->ebx, proc_current()); - } else if (ready != EOK) { + if (ready != EOK) { frame->eax = ready; break; } diff --git a/kernel/inc/dev.h b/kernel/inc/dev.h index fc5e424..c824009 100644 --- a/kernel/inc/dev.h +++ b/kernel/inc/dev.h @@ -17,6 +17,7 @@ struct dev_dev { void dev_install(void); void dev_add(enum dev_type type, struct dev_dev *dev) NONNULL; +void dev_remove_proc(struct proc *proc) NONNULL; // No NONNULL on syscalls res dev_control(enum dev_type type, u32 request, void *arg1, void *arg2, void *arg3); diff --git a/kernel/inc/proc.h b/kernel/inc/proc.h index b2e5c8b..42ff75d 100644 --- a/kernel/inc/proc.h +++ b/kernel/inc/proc.h @@ -66,7 +66,7 @@ void proc_set_quantum(struct proc *proc, u32 value) NONNULL; void proc_reset_quantum(struct proc *proc) NONNULL; void proc_state(struct proc *proc, enum proc_state state) NONNULL; struct proc *proc_make(enum proc_priv priv); -void proc_make_regs(struct proc *proc); +void proc_make_regs(struct proc *proc) NONNULL; void proc_stack_user_push(struct proc *proc, const void *data, u32 size) NONNULL; void proc_stack_kernel_push(struct proc *proc, const void *data, u32 size) NONNULL; diff --git a/libs/libgui/msg.c b/libs/libgui/msg.c index a8da87c..16f72d4 100644 --- a/libs/libgui/msg.c +++ b/libs/libgui/msg.c @@ -35,8 +35,11 @@ res msg_send(enum message_type type, void *data, u32 size) res msg_receive(void *buf, u32 size) { - res ret = dev_read(DEV_BUS, buf, 0, size); + assert(size >= sizeof(struct message_header)); struct message_header *header = buf; + memset(header, 0, sizeof(*header)); + + res ret = dev_read(DEV_BUS, buf, 0, size); if (header->magic == MSG_MAGIC) return ret; else |