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:
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
|
||||
Reference in New Issue
Block a user