mirror of
https://github.com/genodelabs/genode.git
synced 2025-05-08 19:48:13 +00:00
vfs_lwip/lwip: Lwip::lock for concurrent access
This is required in case the send and receive of IP packets is performed by multiple thread because lwip is not thread safe. issue #3568
This commit is contained in:
parent
9812799b24
commit
9767c4db0e
@ -17,6 +17,10 @@
|
|||||||
#include <timer/timeout.h>
|
#include <timer/timeout.h>
|
||||||
#include <base/allocator.h>
|
#include <base/allocator.h>
|
||||||
|
|
||||||
namespace Lwip { void genode_init(Genode::Allocator &heap, Genode::Timeout_scheduler &timer); }
|
namespace Lwip {
|
||||||
|
void genode_init(Genode::Allocator &heap, Genode::Timeout_scheduler &timer);
|
||||||
|
|
||||||
|
Genode::Lock &lock();
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Genode includes */
|
/* Genode includes */
|
||||||
|
#include <lwip/genode_init.h>
|
||||||
#include <nic/packet_allocator.h>
|
#include <nic/packet_allocator.h>
|
||||||
#include <nic_session/connection.h>
|
#include <nic_session/connection.h>
|
||||||
#include <base/log.h>
|
#include <base/log.h>
|
||||||
@ -140,6 +141,7 @@ class Lwip::Nic_netif
|
|||||||
|
|
||||||
void handle_rx_packets()
|
void handle_rx_packets()
|
||||||
{
|
{
|
||||||
|
Genode::Lock::Guard g { Lwip::lock() };
|
||||||
auto &rx = *_nic.rx();
|
auto &rx = *_nic.rx();
|
||||||
|
|
||||||
while (rx.packet_avail() && rx.ready_to_ack()) {
|
while (rx.packet_avail() && rx.ready_to_ack()) {
|
||||||
|
@ -36,8 +36,11 @@ namespace Lwip {
|
|||||||
|
|
||||||
struct Sys_timer
|
struct Sys_timer
|
||||||
{
|
{
|
||||||
void check_timeouts(Genode::Duration) {
|
void check_timeouts(Genode::Duration)
|
||||||
sys_check_timeouts(); }
|
{
|
||||||
|
Genode::Lock::Guard g{ Lwip::lock() };
|
||||||
|
sys_check_timeouts();
|
||||||
|
}
|
||||||
|
|
||||||
Genode::Timeout_scheduler &timer;
|
Genode::Timeout_scheduler &timer;
|
||||||
|
|
||||||
@ -62,6 +65,12 @@ namespace Lwip {
|
|||||||
|
|
||||||
lwip_init();
|
lwip_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Genode::Lock &lock()
|
||||||
|
{
|
||||||
|
static Genode::Lock _lwip_lock;
|
||||||
|
return _lwip_lock;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -898,6 +898,7 @@ class Lwip::Udp_socket_dir final :
|
|||||||
char *dst, file_size count,
|
char *dst, file_size count,
|
||||||
file_size &out_count) override
|
file_size &out_count) override
|
||||||
{
|
{
|
||||||
|
Genode::Lock::Guard g { Lwip::lock() };
|
||||||
Read_result result = Read_result::READ_ERR_INVALID;
|
Read_result result = Read_result::READ_ERR_INVALID;
|
||||||
|
|
||||||
switch(handle.kind) {
|
switch(handle.kind) {
|
||||||
@ -983,6 +984,8 @@ class Lwip::Udp_socket_dir final :
|
|||||||
char const *src, file_size count,
|
char const *src, file_size count,
|
||||||
file_size &out_count) override
|
file_size &out_count) override
|
||||||
{
|
{
|
||||||
|
Genode::Lock::Guard g { Lwip::lock() };
|
||||||
|
|
||||||
switch(handle.kind) {
|
switch(handle.kind) {
|
||||||
|
|
||||||
case Lwip_file_handle::DATA: {
|
case Lwip_file_handle::DATA: {
|
||||||
@ -1287,6 +1290,8 @@ class Lwip::Tcp_socket_dir final :
|
|||||||
char *dst, file_size count,
|
char *dst, file_size count,
|
||||||
file_size &out_count) override
|
file_size &out_count) override
|
||||||
{
|
{
|
||||||
|
Genode::Lock::Guard g { Lwip::lock() };
|
||||||
|
|
||||||
switch(handle.kind) {
|
switch(handle.kind) {
|
||||||
|
|
||||||
case Lwip_file_handle::DATA:
|
case Lwip_file_handle::DATA:
|
||||||
@ -1371,7 +1376,11 @@ class Lwip::Tcp_socket_dir final :
|
|||||||
|
|
||||||
handle.kind = Lwip_file_handle::LOCATION;
|
handle.kind = Lwip_file_handle::LOCATION;
|
||||||
/* read the location of the new socket directory */
|
/* read the location of the new socket directory */
|
||||||
return handle.read(dst, count, out_count);
|
Lwip::lock().unlock();
|
||||||
|
Read_result result = handle.read(dst, count, out_count);
|
||||||
|
Lwip::lock().lock();
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Read_result::READ_QUEUED;
|
return Read_result::READ_QUEUED;
|
||||||
@ -1433,6 +1442,7 @@ class Lwip::Tcp_socket_dir final :
|
|||||||
char const *src, file_size count,
|
char const *src, file_size count,
|
||||||
file_size &out_count) override
|
file_size &out_count) override
|
||||||
{
|
{
|
||||||
|
Genode::Lock::Guard g { Lwip::lock() };
|
||||||
if (_pcb == NULL) {
|
if (_pcb == NULL) {
|
||||||
/* socket is closed */
|
/* socket is closed */
|
||||||
return Write_result::WRITE_ERR_IO;
|
return Write_result::WRITE_ERR_IO;
|
||||||
@ -1958,17 +1968,8 @@ class Lwip::File_system final : public Vfs::File_system, public Lwip::Directory
|
|||||||
if ((vfs_handle->status_flags() & OPEN_MODE_ACCMODE) == OPEN_MODE_RDONLY)
|
if ((vfs_handle->status_flags() & OPEN_MODE_ACCMODE) == OPEN_MODE_RDONLY)
|
||||||
return Write_result::WRITE_ERR_INVALID;
|
return Write_result::WRITE_ERR_INVALID;
|
||||||
if (Lwip_handle *handle = dynamic_cast<Lwip_handle*>(vfs_handle)) {
|
if (Lwip_handle *handle = dynamic_cast<Lwip_handle*>(vfs_handle)) {
|
||||||
while (true) {
|
res = handle->write(src, count, out_count);
|
||||||
res = handle->write(src, count, out_count);
|
if (res == WRITE_ERR_WOULD_BLOCK) throw Insufficient_buffer();
|
||||||
if (res != WRITE_ERR_WOULD_BLOCK || out_count) break;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* XXX: block for signals until the write completes
|
|
||||||
* or fails, this is not how it should be done, but
|
|
||||||
* it's how lxip does it
|
|
||||||
*/
|
|
||||||
_ep.wait_and_dispatch_one_io_signal();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user