Compare commits

..

2 Commits

Author SHA1 Message Date
56066f332f
wind: Handle ftruncate() and mmap() errors properly
Some checks failed
continuous-integration/drone/pr Build is failing
2023-08-17 11:20:32 +02:00
d535c10061
wind: Fix client references being out-of-date in windows when disconnecting other clients
Classic "keeping a pointer to an element inside a vector after the vector is updated" bug, ah yes.
2023-08-16 20:02:54 +02:00
3 changed files with 24 additions and 13 deletions

View File

@ -8,4 +8,11 @@ struct Client
Vector<Window*> windows; Vector<Window*> windows;
bool rpc_in_progress { false }; bool rpc_in_progress { false };
u8 rpc_id { 0 }; u8 rpc_id { 0 };
Client(os::LocalServer::Client&& client)
#ifdef CLIENT_IMPLEMENTATION
: conn(move(client)), windows() {}
#else
;
#endif
}; };

View File

@ -26,29 +26,32 @@ static Result<u32*> create_shm_region(const char* path, int* outfd, ui::Rect rec
int fd = shm_open(path, O_RDWR | O_CREAT | O_EXCL, 0600); int fd = shm_open(path, O_RDWR | O_CREAT | O_EXCL, 0600);
if (fd < 0) if (fd < 0)
{ {
os::eprintln("wind: could not create shared memory region: shm_open failed (%s) - %s", path, strerror(errno)); int olderr = errno;
return err(errno); os::eprintln("wind: could not create shared memory region: shm_open failed (%s) - %s", path, strerror(olderr));
return err(olderr);
} }
usize size = align_up<PAGE_SIZE>(rect.width * rect.height * 4); // 4 bytes per pixel usize size = align_up<PAGE_SIZE>(rect.width * rect.height * 4); // 4 bytes per pixel
if (ftruncate(fd, size) < 0) if (ftruncate(fd, size) < 0)
{ {
int olderr = errno;
os::eprintln("wind: could not create shared memory region: ftruncate failed (%d, %zu) - %s", fd, size, os::eprintln("wind: could not create shared memory region: ftruncate failed (%d, %zu) - %s", fd, size,
strerror(errno)); strerror(olderr));
shm_unlink(path); shm_unlink(path);
close(fd); close(fd);
return 0; return err(olderr);
} }
void* p = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); void* p = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (p == MAP_FAILED) if (p == MAP_FAILED)
{ {
int olderr = errno;
os::eprintln("wind: could not create shared memory region: mmap failed (%zu, %d) - %s", size, fd, os::eprintln("wind: could not create shared memory region: mmap failed (%zu, %d) - %s", size, fd,
strerror(errno)); strerror(olderr));
shm_unlink(path); shm_unlink(path);
close(fd); close(fd);
return 0; return err(olderr);
} }
if (outfd) *outfd = fd; if (outfd) *outfd = fd;

View File

@ -1,3 +1,4 @@
#define CLIENT_IMPLEMENTATION
#include "Client.h" #include "Client.h"
#include "IPC.h" #include "IPC.h"
#include "Mouse.h" #include "Mouse.h"
@ -18,7 +19,7 @@
#include <time.h> #include <time.h>
#include <unistd.h> #include <unistd.h>
static void debug(const Vector<Client>& clients) static void debug(const Vector<OwnedPtr<Client>>& clients)
{ {
os::println("--- wind: DEBUG OUTPUT ---"); os::println("--- wind: DEBUG OUTPUT ---");
@ -26,7 +27,7 @@ static void debug(const Vector<Client>& clients)
for (const auto& client : clients) for (const auto& client : clients)
{ {
os::println("Client with fd %d, owns %zu windows", client.conn.fd(), client.windows.size()); os::println("Client with fd %d, owns %zu windows", client->conn.fd(), client->windows.size());
} }
os::println("-- wind: Listing windows --"); os::println("-- wind: Listing windows --");
@ -113,7 +114,7 @@ Result<int> luna_main(int argc, char** argv)
ui::Color background = ui::BLACK; ui::Color background = ui::BLACK;
Vector<Client> clients; Vector<OwnedPtr<Client>> clients;
Vector<struct pollfd> fds; Vector<struct pollfd> fds;
TRY(fds.try_append({ .fd = mouse->fd(), .events = POLLIN, .revents = 0 })); TRY(fds.try_append({ .fd = mouse->fd(), .events = POLLIN, .revents = 0 }));
TRY(fds.try_append({ .fd = keyboard->fd(), .events = POLLIN, .revents = 0 })); TRY(fds.try_append({ .fd = keyboard->fd(), .events = POLLIN, .revents = 0 }));
@ -149,14 +150,14 @@ Result<int> luna_main(int argc, char** argv)
} }
for (usize i = 0; i < clients.size(); i++) for (usize i = 0; i < clients.size(); i++)
{ {
if (fds[i + 3].revents & POLLIN) wind::handle_ipc(clients[i]); if (fds[i + 3].revents & POLLIN) wind::handle_ipc(*clients[i]);
if (fds[i + 3].revents & POLLHUP) if (fds[i + 3].revents & POLLHUP)
{ {
os::println("wind: Client %d disconnected", i); os::println("wind: Client %d disconnected", i);
fds.remove_at(i + 3); fds.remove_at(i + 3);
auto client = clients.remove_at(i); auto client = clients.remove_at(i);
client.conn.disconnect(); client->conn.disconnect();
for (auto& window : client.windows) for (auto& window : client->windows)
{ {
if (window) if (window)
{ {
@ -171,7 +172,7 @@ Result<int> luna_main(int argc, char** argv)
auto client = TRY(server->accept()); auto client = TRY(server->accept());
os::println("wind: New client connected!"); os::println("wind: New client connected!");
TRY(fds.try_append({ .fd = client.fd(), .events = POLLIN, .revents = 0 })); TRY(fds.try_append({ .fd = client.fd(), .events = POLLIN, .revents = 0 }));
Client c { move(client), {} }; OwnedPtr<Client> c = TRY(adopt_owned_if_nonnull(new Client(move(client))));
TRY(clients.try_append(move(c))); TRY(clients.try_append(move(c)));
} }
} }