loop: no longer requires a reader thread, it delivers directly to the device's receive queue

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21215 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Hugo Santos
2007-05-23 07:56:15 +00:00
parent a1deb55ef5
commit 969885b848
6 changed files with 52 additions and 74 deletions
+3
View File
@@ -101,6 +101,9 @@ struct net_stack_module_info {
status_t (*device_link_changed)(struct net_device *device);
status_t (*device_removed)(struct net_device *device);
status_t (*device_enqueue_buffer)(struct net_device *device,
struct net_buffer *buffer);
// Utility Functions
// notification
@@ -22,7 +22,6 @@
struct loopback_device : net_device {
net_fifo fifo;
};
@@ -30,34 +29,6 @@ struct net_buffer_module_info *gBufferModule;
static struct net_stack_module_info *sStackModule;
/*!
Swaps \a size bytes of the memory pointed to by \a and \b with each other.
*/
void
swap_memory(void *a, void *b, size_t size)
{
uint32 *a4 = (uint32 *)a;
uint32 *b4 = (uint32 *)b;
while (size > 4) {
uint32 temp = *a4;
*(a4++) = *b4;
*(b4++) = temp;
size -= 4;
}
uint8 *a1 = (uint8 *)a4;
uint8 *b1 = (uint8 *)b4;
while (size > 0) {
uint8 temp = *a1;
*(a1++) = *b1;
*(b1++) = temp;
size--;
}
}
// #pragma mark -
@@ -116,18 +87,15 @@ loopback_uninit(net_device *_device)
status_t
loopback_up(net_device *_device)
loopback_up(net_device *device)
{
loopback_device *device = (loopback_device *)_device;
return sStackModule->init_fifo(&device->fifo, "loopback fifo", 65536);
return B_OK;
}
void
loopback_down(net_device *_device)
loopback_down(net_device *device)
{
loopback_device *device = (loopback_device *)_device;
sStackModule->uninit_fifo(&device->fifo);
}
@@ -140,36 +108,18 @@ loopback_control(net_device *device, int32 op, void *argument,
status_t
loopback_send_data(net_device *_device, net_buffer *buffer)
loopback_send_data(net_device *device, net_buffer *buffer)
{
loopback_device *device = (loopback_device *)_device;
return sStackModule->fifo_enqueue_buffer(&device->fifo, buffer);
}
status_t
loopback_receive_data(net_device *_device, net_buffer **_buffer)
{
loopback_device *device = (loopback_device *)_device;
net_buffer *buffer;
status_t status = sStackModule->fifo_dequeue_buffer(&device->fifo, 0, 0, &buffer);
if (status < B_OK)
return status;
// swap network addresses before delivering
gBufferModule->swap_addresses(buffer);
*_buffer = buffer;
return B_OK;
return sStackModule->device_enqueue_buffer(device, buffer);
}
status_t
loopback_set_mtu(net_device *device, size_t mtu)
{
if (mtu > 65536
|| mtu < 16)
if (mtu > 65536 || mtu < 16)
return B_BAD_VALUE;
device->mtu = mtu;
@@ -231,7 +181,7 @@ net_device_module_info sLoopbackModule = {
loopback_down,
loopback_control,
loopback_send_data,
loopback_receive_data,
NULL, // receive_data
loopback_set_mtu,
loopback_set_promiscuous,
loopback_set_media,
+13 -8
View File
@@ -555,17 +555,22 @@ interface_protocol_up(net_datalink_protocol *_protocol)
if (status < B_OK)
return status;
// give the thread a nice name
char name[B_OS_NAME_LENGTH];
snprintf(name, sizeof(name), "%s reader", device->name);
if (device->module->receive_data != NULL) {
// give the thread a nice name
char name[B_OS_NAME_LENGTH];
snprintf(name, sizeof(name), "%s reader", device->name);
deviceInterface->reader_thread = spawn_kernel_thread(device_reader_thread, name,
B_REAL_TIME_DISPLAY_PRIORITY - 10, deviceInterface);
if (deviceInterface->reader_thread < B_OK)
return deviceInterface->reader_thread;
deviceInterface->reader_thread =
spawn_kernel_thread(device_reader_thread, name,
B_REAL_TIME_DISPLAY_PRIORITY - 10, deviceInterface);
if (deviceInterface->reader_thread < B_OK)
return deviceInterface->reader_thread;
}
device->flags |= IFF_UP;
resume_thread(deviceInterface->reader_thread);
if (device->module->receive_data != NULL)
resume_thread(deviceInterface->reader_thread);
deviceInterface->up_count = 1;
return B_OK;
@@ -551,19 +551,22 @@ down_device_interface(net_device_interface *interface)
notify_device_monitors(interface, B_DEVICE_GOING_DOWN);
thread_id reader_thread = interface->reader_thread;
if (device->module->receive_data != NULL) {
thread_id reader_thread = interface->reader_thread;
// TODO when setting the interface down, should we clear the receive queue?
// TODO when setting the interface down,
// should we clear the receive queue?
// one of the callers must hold a reference to the net_device_interface
// usually it is one of the net_interfaces.
recursive_lock_unlock(&interface->rx_lock);
// one of the callers must hold a reference to the net_device_interface
// usually it is one of the net_interfaces.
recursive_lock_unlock(&interface->rx_lock);
// make sure the reader thread is gone before shutting down the interface
status_t status;
wait_for_thread(reader_thread, &status);
// make sure the reader thread is gone before shutting down the interface
status_t status;
wait_for_thread(reader_thread, &status);
recursive_lock_lock(&interface->rx_lock);
recursive_lock_lock(&interface->rx_lock);
}
}
@@ -804,6 +807,21 @@ device_removed(net_device *device)
}
status_t
device_enqueue_buffer(net_device *device, net_buffer *buffer)
{
net_device_interface *interface = get_device_interface(device->index);
if (interface == NULL)
return ENODEV;
status_t status = fifo_enqueue_buffer(&interface->receive_queue, buffer);
put_device_interface(interface);
return status;
}
// #pragma mark -
@@ -97,5 +97,6 @@ status_t unregister_device_monitor(struct net_device *device,
struct net_device_monitor *monitor);
status_t device_link_changed(net_device *device);
status_t device_removed(net_device *device);
status_t device_enqueue_buffer(net_device *device, net_buffer *buffer);
#endif // INTERFACES_H
@@ -923,6 +923,7 @@ net_stack_module_info gNetStackModule = {
unregister_device_monitor,
device_link_changed,
device_removed,
device_enqueue_buffer,
notify_socket,