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_link_changed)(struct net_device *device);
|
||||||
status_t (*device_removed)(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
|
// Utility Functions
|
||||||
|
|
||||||
// notification
|
// notification
|
||||||
|
|||||||
@@ -22,7 +22,6 @@
|
|||||||
|
|
||||||
|
|
||||||
struct loopback_device : net_device {
|
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;
|
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 -
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
@@ -116,18 +87,15 @@ loopback_uninit(net_device *_device)
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
loopback_up(net_device *_device)
|
loopback_up(net_device *device)
|
||||||
{
|
{
|
||||||
loopback_device *device = (loopback_device *)_device;
|
return B_OK;
|
||||||
return sStackModule->init_fifo(&device->fifo, "loopback fifo", 65536);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
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
|
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);
|
gBufferModule->swap_addresses(buffer);
|
||||||
|
|
||||||
*_buffer = buffer;
|
return sStackModule->device_enqueue_buffer(device, buffer);
|
||||||
return B_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
loopback_set_mtu(net_device *device, size_t mtu)
|
loopback_set_mtu(net_device *device, size_t mtu)
|
||||||
{
|
{
|
||||||
if (mtu > 65536
|
if (mtu > 65536 || mtu < 16)
|
||||||
|| mtu < 16)
|
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
device->mtu = mtu;
|
device->mtu = mtu;
|
||||||
@@ -231,7 +181,7 @@ net_device_module_info sLoopbackModule = {
|
|||||||
loopback_down,
|
loopback_down,
|
||||||
loopback_control,
|
loopback_control,
|
||||||
loopback_send_data,
|
loopback_send_data,
|
||||||
loopback_receive_data,
|
NULL, // receive_data
|
||||||
loopback_set_mtu,
|
loopback_set_mtu,
|
||||||
loopback_set_promiscuous,
|
loopback_set_promiscuous,
|
||||||
loopback_set_media,
|
loopback_set_media,
|
||||||
|
|||||||
@@ -555,17 +555,22 @@ interface_protocol_up(net_datalink_protocol *_protocol)
|
|||||||
if (status < B_OK)
|
if (status < B_OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
// give the thread a nice name
|
if (device->module->receive_data != NULL) {
|
||||||
char name[B_OS_NAME_LENGTH];
|
// give the thread a nice name
|
||||||
snprintf(name, sizeof(name), "%s reader", device->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,
|
deviceInterface->reader_thread =
|
||||||
B_REAL_TIME_DISPLAY_PRIORITY - 10, deviceInterface);
|
spawn_kernel_thread(device_reader_thread, name,
|
||||||
if (deviceInterface->reader_thread < B_OK)
|
B_REAL_TIME_DISPLAY_PRIORITY - 10, deviceInterface);
|
||||||
return deviceInterface->reader_thread;
|
if (deviceInterface->reader_thread < B_OK)
|
||||||
|
return deviceInterface->reader_thread;
|
||||||
|
}
|
||||||
|
|
||||||
device->flags |= IFF_UP;
|
device->flags |= IFF_UP;
|
||||||
resume_thread(deviceInterface->reader_thread);
|
|
||||||
|
if (device->module->receive_data != NULL)
|
||||||
|
resume_thread(deviceInterface->reader_thread);
|
||||||
|
|
||||||
deviceInterface->up_count = 1;
|
deviceInterface->up_count = 1;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|||||||
@@ -551,19 +551,22 @@ down_device_interface(net_device_interface *interface)
|
|||||||
|
|
||||||
notify_device_monitors(interface, B_DEVICE_GOING_DOWN);
|
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
|
// one of the callers must hold a reference to the net_device_interface
|
||||||
// usually it is one of the net_interfaces.
|
// usually it is one of the net_interfaces.
|
||||||
recursive_lock_unlock(&interface->rx_lock);
|
recursive_lock_unlock(&interface->rx_lock);
|
||||||
|
|
||||||
// make sure the reader thread is gone before shutting down the interface
|
// make sure the reader thread is gone before shutting down the interface
|
||||||
status_t status;
|
status_t status;
|
||||||
wait_for_thread(reader_thread, &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 -
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -97,5 +97,6 @@ status_t unregister_device_monitor(struct net_device *device,
|
|||||||
struct net_device_monitor *monitor);
|
struct net_device_monitor *monitor);
|
||||||
status_t device_link_changed(net_device *device);
|
status_t device_link_changed(net_device *device);
|
||||||
status_t device_removed(net_device *device);
|
status_t device_removed(net_device *device);
|
||||||
|
status_t device_enqueue_buffer(net_device *device, net_buffer *buffer);
|
||||||
|
|
||||||
#endif // INTERFACES_H
|
#endif // INTERFACES_H
|
||||||
|
|||||||
@@ -923,6 +923,7 @@ net_stack_module_info gNetStackModule = {
|
|||||||
unregister_device_monitor,
|
unregister_device_monitor,
|
||||||
device_link_changed,
|
device_link_changed,
|
||||||
device_removed,
|
device_removed,
|
||||||
|
device_enqueue_buffer,
|
||||||
|
|
||||||
notify_socket,
|
notify_socket,
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user