mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-11-01 23:18:21 +00:00
mouse: fix deadlock
This commit is contained in:
@@ -137,6 +137,7 @@ typedef struct {
|
|||||||
#define SIOCGIFHWADDR 0x8927
|
#define SIOCGIFHWADDR 0x8927
|
||||||
#define SIOCADDRT 0x890b
|
#define SIOCADDRT 0x890b
|
||||||
#define SIOCSIFADDR 0x8916
|
#define SIOCSIFADDR 0x8916
|
||||||
|
#define FIONREAD 0x541B
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char name[IFNAMSIZ];
|
char name[IFNAMSIZ];
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <ringbuffer.h>
|
#include <ringbuffer.h>
|
||||||
#include <kernel/poll.h>
|
#include <kernel/poll.h>
|
||||||
|
#include <mutex.h>
|
||||||
|
|
||||||
#define MOUSE_FLAG_RB 1
|
#define MOUSE_FLAG_RB 1
|
||||||
#define MOUSE_FLAG_MB 2
|
#define MOUSE_FLAG_MB 2
|
||||||
@@ -20,6 +21,7 @@ typedef struct {
|
|||||||
spinlock_t lock;
|
spinlock_t lock;
|
||||||
pollheader_t pollheader;
|
pollheader_t pollheader;
|
||||||
int flags;
|
int flags;
|
||||||
|
mutex_t readmutex;
|
||||||
} mouse_t;
|
} mouse_t;
|
||||||
|
|
||||||
void mouse_init();
|
void mouse_init();
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ typedef struct socketops_t {
|
|||||||
int (*connect)(socket_t *socket, sockaddr_t *addr, uintmax_t data);
|
int (*connect)(socket_t *socket, sockaddr_t *addr, uintmax_t data);
|
||||||
int (*listen)(socket_t *socket, int backlog);
|
int (*listen)(socket_t *socket, int backlog);
|
||||||
int (*accept)(socket_t *server, socket_t *client, sockaddr_t *addr, uintmax_t flags);
|
int (*accept)(socket_t *server, socket_t *client, sockaddr_t *addr, uintmax_t flags);
|
||||||
|
size_t (*datacount)(socket_t *socket);
|
||||||
void (*destroy)(socket_t *socket);
|
void (*destroy)(socket_t *socket);
|
||||||
} socketops_t;
|
} socketops_t;
|
||||||
|
|
||||||
|
|||||||
@@ -172,8 +172,8 @@ int vfs_unlink(vnode_t *ref, char *path);
|
|||||||
int vfs_pollstub(vnode_t *node, struct polldata *, int events);
|
int vfs_pollstub(vnode_t *node, struct polldata *, int events);
|
||||||
void vfs_inactive(vnode_t *node);
|
void vfs_inactive(vnode_t *node);
|
||||||
|
|
||||||
#define VFS_LOOKUP_PARENT 1
|
#define VFS_LOOKUP_PARENT 0x20000000
|
||||||
#define VFS_LOOKUP_NOLINK 2
|
#define VFS_LOOKUP_NOLINK 0x40000000
|
||||||
#define VFS_LOOKUP_INTERNAL 0x80000000
|
#define VFS_LOOKUP_INTERNAL 0x80000000
|
||||||
int vfs_lookup(vnode_t **result, vnode_t *start, char *path, char *lastcomp, int flags);
|
int vfs_lookup(vnode_t **result, vnode_t *start, char *path, char *lastcomp, int flags);
|
||||||
|
|
||||||
|
|||||||
+19
-8
@@ -23,6 +23,7 @@ static mouse_t *newmouse() {
|
|||||||
|
|
||||||
POLL_INITHEADER(&mouse->pollheader);
|
POLL_INITHEADER(&mouse->pollheader);
|
||||||
SPINLOCK_INIT(mouse->lock);
|
SPINLOCK_INIT(mouse->lock);
|
||||||
|
MUTEX_INIT(&mouse->readmutex);
|
||||||
|
|
||||||
return mouse;
|
return mouse;
|
||||||
}
|
}
|
||||||
@@ -77,11 +78,7 @@ static int read(int minor, void *buffer, size_t size, uintmax_t offset, int flag
|
|||||||
if (packetcount == 0)
|
if (packetcount == 0)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
// disable interrupts here as to not lose any interrupts
|
MUTEX_ACQUIRE(&mouse->readmutex, false);
|
||||||
// and because we cannot sleep with a raised ipl
|
|
||||||
bool oldintstatus = interrupt_set(false);
|
|
||||||
spinlock_acquire(&mouse->lock);
|
|
||||||
|
|
||||||
// wait until there is data to read or return if nonblock
|
// wait until there is data to read or return if nonblock
|
||||||
for (;;) {
|
for (;;) {
|
||||||
polldesc_t desc = {0};
|
polldesc_t desc = {0};
|
||||||
@@ -89,22 +86,33 @@ static int read(int minor, void *buffer, size_t size, uintmax_t offset, int flag
|
|||||||
if (error)
|
if (error)
|
||||||
goto leave;
|
goto leave;
|
||||||
|
|
||||||
|
// disable interrupts here as to not lose any interrupts
|
||||||
|
// and because we cannot sleep with a raised ipl
|
||||||
|
bool oldintstatus = interrupt_set(false);
|
||||||
|
spinlock_acquire(&mouse->lock);
|
||||||
|
|
||||||
int revents = internalpoll(mouse, &desc.data[0], POLLIN);
|
int revents = internalpoll(mouse, &desc.data[0], POLLIN);
|
||||||
|
|
||||||
if (revents) {
|
if (revents) {
|
||||||
|
spinlock_release(&mouse->lock);
|
||||||
|
interrupt_set(oldintstatus);
|
||||||
poll_leave(&desc);
|
poll_leave(&desc);
|
||||||
poll_destroydesc(&desc);
|
poll_destroydesc(&desc);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (revents == 0 && flags & V_FFLAGS_NONBLOCKING) {
|
if (revents == 0 && flags & V_FFLAGS_NONBLOCKING) {
|
||||||
|
spinlock_release(&mouse->lock);
|
||||||
|
interrupt_set(oldintstatus);
|
||||||
|
poll_leave(&desc);
|
||||||
|
poll_destroydesc(&desc);
|
||||||
error = EAGAIN;
|
error = EAGAIN;
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
spinlock_release(&mouse->lock);
|
spinlock_release(&mouse->lock);
|
||||||
error = poll_dowait(&desc, 0);
|
error = poll_dowait(&desc, 0);
|
||||||
spinlock_acquire(&mouse->lock);
|
interrupt_set(oldintstatus);
|
||||||
|
|
||||||
poll_leave(&desc);
|
poll_leave(&desc);
|
||||||
poll_destroydesc(&desc);
|
poll_destroydesc(&desc);
|
||||||
@@ -117,8 +125,7 @@ static int read(int minor, void *buffer, size_t size, uintmax_t offset, int flag
|
|||||||
__assert(*readc);
|
__assert(*readc);
|
||||||
|
|
||||||
leave:
|
leave:
|
||||||
spinlock_release(&mouse->lock);
|
MUTEX_RELEASE(&mouse->readmutex);
|
||||||
interrupt_set(oldintstatus);
|
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
@@ -128,12 +135,16 @@ static int poll(int minor, polldata_t *data, int events) {
|
|||||||
if (mouse == NULL)
|
if (mouse == NULL)
|
||||||
return POLLERR;
|
return POLLERR;
|
||||||
|
|
||||||
|
MUTEX_ACQUIRE(&mouse->readmutex, false);
|
||||||
|
|
||||||
long ipl = interrupt_raiseipl(IPL_MOUSE);
|
long ipl = interrupt_raiseipl(IPL_MOUSE);
|
||||||
spinlock_acquire(&mouse->lock);
|
spinlock_acquire(&mouse->lock);
|
||||||
int revents = internalpoll(mouse, data, events);
|
int revents = internalpoll(mouse, data, events);
|
||||||
spinlock_release(&mouse->lock);
|
spinlock_release(&mouse->lock);
|
||||||
interrupt_loweripl(ipl);
|
interrupt_loweripl(ipl);
|
||||||
|
|
||||||
|
MUTEX_RELEASE(&mouse->readmutex);
|
||||||
|
|
||||||
return revents;
|
return revents;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user