Handle all slirp input/output from a single thread, thus fixing occasional

hangs on slower systems (concurrent read/write in 68k mode). Reduce timeout
to 10 ms.
This commit is contained in:
gbeauche 2005-05-21 17:48:21 +00:00
parent 02714e46a8
commit a4caa8ab09

View File

@ -93,6 +93,7 @@ static const char *net_if_script = NULL; // Network config script
static pthread_t slirp_thread; // Slirp reception thread
static bool slirp_thread_active = false; // Flag: Slirp reception threadinstalled
static int slirp_output_fd = -1; // fd of slirp output pipe
static int slirp_input_fds[2] = { -1, -1 }; // fds of slirp input pipe
// Attached network protocols, maps protocol type to MacOS handler address
static map<uint16, uint32> net_protocols;
@ -231,6 +232,10 @@ bool ether_init(void)
return false;
fd = fds[0];
slirp_output_fd = fds[1];
// Open slirp input pipe
if (pipe(slirp_input_fds) < 0)
return false;
}
#endif
@ -338,6 +343,14 @@ open_error:
close(fd);
fd = -1;
}
if (slirp_input_fds[0] >= 0) {
close(slirp_input_fds[0]);
slirp_input_fds[0] = -1;
}
if (slirp_input_fds[1] >= 0) {
close(slirp_input_fds[1]);
slirp_input_fds[1] = -1;
}
if (slirp_output_fd >= 0) {
close(slirp_output_fd);
slirp_output_fd = -1;
@ -367,6 +380,12 @@ void ether_exit(void)
if (fd > 0)
close(fd);
// Close slirp input buffer
if (slirp_input_fds[0] >= 0)
close(slirp_input_fds[0]);
if (slirp_input_fds[1] >= 0)
close(slirp_input_fds[1]);
// Close slirp output buffer
if (slirp_output_fd > 0)
close(slirp_output_fd);
@ -478,7 +497,9 @@ int16 ether_write(uint32 wds)
// Transmit packet
#ifdef HAVE_SLIRP
if (net_if_type == NET_IF_SLIRP) {
slirp_input(packet, len);
const int slirp_input_fd = slirp_input_fds[1];
write(slirp_input_fd, &len, sizeof(len));
write(slirp_input_fd, packet, len);
return noErr;
} else
#endif
@ -530,19 +551,36 @@ void slirp_output(const uint8 *packet, int len)
void *slirp_receive_func(void *arg)
{
const int slirp_input_fd = slirp_input_fds[0];
for (;;) {
// Wait for packets to arrive
fd_set rfds, wfds, xfds;
int nfds;
struct timeval tv;
// ... in the input queue
FD_ZERO(&rfds);
FD_SET(slirp_input_fd, &rfds);
tv.tv_sec = 0;
tv.tv_usec = 0;
if (select(slirp_input_fd + 1, &rfds, NULL, NULL, &tv) > 0) {
int len;
read(slirp_input_fd, &len, sizeof(len));
uint8 packet[1516];
assert(len <= sizeof(packet));
read(slirp_input_fd, packet, len);
slirp_input(packet, len);
}
// ... in the output queue
nfds = -1;
FD_ZERO(&rfds);
FD_ZERO(&wfds);
FD_ZERO(&xfds);
slirp_select_fill(&nfds, &rfds, &wfds, &xfds);
tv.tv_sec = 0;
tv.tv_usec = 16667;
tv.tv_usec = 10000;
if (select(nfds + 1, &rfds, &wfds, &xfds, &tv) >= 0)
slirp_select_poll(&rfds, &wfds, &xfds);