* Renamed net_device_interface::rx_lock to receive_lock.

* Cleanup, improved comments, removed useless ones.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@29232 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2009-02-16 11:13:28 +00:00
parent 86a0cf15e4
commit 3c13a5f5b3
4 changed files with 364 additions and 405 deletions
+13 -22
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright 2006-2008, Haiku, Inc. All Rights Reserved. * Copyright 2006-2009, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
@@ -47,9 +47,9 @@ device_reader_thread(void *_interface)
net_device* device = interface->device; net_device* device = interface->device;
status_t status = B_OK; status_t status = B_OK;
RecursiveLocker locker(interface->rx_lock); RecursiveLocker locker(interface->receive_lock);
while (device->flags & IFF_UP) { while ((device->flags & IFF_UP) != 0) {
locker.Unlock(); locker.Unlock();
net_buffer* buffer; net_buffer* buffer;
@@ -61,8 +61,7 @@ device_reader_thread(void *_interface)
// feed device monitors // feed device monitors
DeviceMonitorList::Iterator iterator = DeviceMonitorList::Iterator iterator =
interface->monitor_funcs.GetIterator(); interface->monitor_funcs.GetIterator();
while (iterator.HasNext()) { while (net_device_monitor* monitor = iterator.Next()) {
net_device_monitor *monitor = iterator.Next();
monitor->receive(monitor, buffer); monitor->receive(monitor, buffer);
} }
@@ -76,18 +75,9 @@ device_reader_thread(void *_interface)
fifo_enqueue_buffer(&interface->receive_queue, buffer); fifo_enqueue_buffer(&interface->receive_queue, buffer);
} else { } else {
// In case of error, give the other threads some // In case of error, give the other threads some
// time to run since this is a near real time thread. // time to run since this is a high priority time thread.
//
// TODO: can this value be lower? 1000 works fine in
// my system. 10ms seems a bit too much and adds
// as latency.
snooze(10000); snooze(10000);
} }
// if the interface went down IFF_UP was removed
// and the receive_data() above should have been
// interrupted. One check should be enough, specially
// considering the snooze above.
} }
return status; return status;
@@ -118,7 +108,7 @@ interface_address(net_interface *interface, int32 option)
} }
void static void
remove_default_routes(net_interface_private* interface, int32 option) remove_default_routes(net_interface_private* interface, int32 option)
{ {
net_route route; net_route route;
@@ -141,7 +131,7 @@ remove_default_routes(net_interface_private *interface, int32 option)
} }
void static void
add_default_routes(net_interface_private* interface, int32 option) add_default_routes(net_interface_private* interface, int32 option)
{ {
net_route route; net_route route;
@@ -164,7 +154,7 @@ add_default_routes(net_interface_private *interface, int32 option)
} }
sockaddr * static sockaddr*
reallocate_address(sockaddr** _address, uint32 size) reallocate_address(sockaddr** _address, uint32 size)
{ {
sockaddr* address = *_address; sockaddr* address = *_address;
@@ -205,7 +195,7 @@ datalink_control_interface(net_domain_private *domain, int32 option,
else else
interface = find_interface(domain, request.ifr_index); interface = find_interface(domain, request.ifr_index);
status_t status = (interface == NULL) ? ENODEV : B_OK; status_t status = interface == NULL ? ENODEV : B_OK;
switch (option) { switch (option) {
case SIOCGIFINDEX: case SIOCGIFINDEX:
@@ -632,11 +622,12 @@ interface_protocol_down(net_datalink_protocol *_protocol)
status_t status_t
interface_protocol_control(net_datalink_protocol *_protocol, interface_protocol_control(net_datalink_protocol* _protocol, int32 option,
int32 option, void *argument, size_t length) void* argument, size_t length)
{ {
interface_protocol* protocol = (interface_protocol*)_protocol; interface_protocol* protocol = (interface_protocol*)_protocol;
net_interface_private *interface = (net_interface_private *)protocol->interface; net_interface_private* interface
= (net_interface_private*)protocol->interface;
switch (option) { switch (option) {
case SIOCSIFADDR: case SIOCSIFADDR:
+22 -31
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright 2006-2008, Haiku, Inc. All Rights Reserved. * Copyright 2006-2009, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
@@ -221,12 +221,11 @@ domain_interface_control(net_domain_private *domain, int32 option,
net_device_interface* device = get_device_interface(name, false); net_device_interface* device = get_device_interface(name, false);
if (device == NULL) if (device == NULL)
return ENODEV; return ENODEV;
else {
// The locking protocol dictates that if both the RX lock // The locking protocol dictates that if both the receive lock
// and domain locks are required, we MUST obtain the RX // and domain locks are required, we MUST obtain the receive
// lock before the domain lock. This order MUST NOT ever // lock before the domain lock.
// be reversed under the penalty of deadlock. RecursiveLocker _1(device->receive_lock);
RecursiveLocker _1(device->rx_lock);
MutexLocker _2(domain->lock); MutexLocker _2(domain->lock);
net_interface* interface = find_interface(domain, name); net_interface* interface = find_interface(domain, name);
@@ -261,40 +260,30 @@ domain_interface_control(net_domain_private *domain, int32 option,
} }
} }
} }
}
// If the SIOCDIFADDR call above removed the last interface // If the SIOCDIFADDR call above removed the last interface associated with
// associated with the device interface, this put_() will // the device interface, this will effectively remove the interface
// effectively remove the interface
put_device_interface(device); put_device_interface(device);
return status; return status;
} }
/*! You need to hold the domain lock when calling this function. */
void void
domain_interface_went_down(net_interface* interface) domain_interface_went_down(net_interface* interface)
{ {
// the domain should be locked here. always check ASSERT_LOCKED_MUTEX(&((net_domain_private*)interface->domain)->lock);
// all callers to be sure. We get here via
// interface_set_down().
dprintf("domain_interface_went_down(%i, %s)\n", TRACE(("domain_interface_went_down(%i, %s)\n",
interface->domain->family, interface->name); interface->domain->family, interface->name));
// domain might have been locked by:
// - domain_removed_device_interface() <--- here
// remove_interface_from_domain()
// delete_interface()
// interface_set_down()
// - datalink_control() <--- here
// interface_set_down()
invalidate_routes(interface->domain, interface); invalidate_routes(interface->domain, interface);
} }
void void
domain_removed_device_interface(net_device_interface *interface) domain_removed_device_interface(net_device_interface* deviceInterface)
{ {
MutexLocker locker(sDomainLock); MutexLocker locker(sDomainLock);
@@ -306,12 +295,12 @@ domain_removed_device_interface(net_device_interface *interface)
MutexLocker locker(domain->lock); MutexLocker locker(domain->lock);
net_interface_private *priv = find_interface(domain, net_interface_private* interface = find_interface(domain,
interface->device->name); deviceInterface->device->name);
if (priv == NULL) if (interface == NULL)
continue; continue;
remove_interface_from_domain(priv); remove_interface_from_domain(interface);
} }
} }
@@ -333,7 +322,7 @@ register_domain(int family, const char *name,
if (domain == NULL) if (domain == NULL)
return B_NO_MEMORY; return B_NO_MEMORY;
mutex_init_etc(&domain->lock, name, MUTEX_FLAG_CLONE_NAME); mutex_init(&domain->lock, name);
domain->family = family; domain->family = family;
domain->name = name; domain->name = name;
@@ -352,7 +341,8 @@ register_domain(int family, const char *name,
status_t status_t
unregister_domain(net_domain* _domain) unregister_domain(net_domain* _domain)
{ {
TRACE(("unregister_domain(%p, %d, %s)\n", _domain, _domain->family, _domain->name)); TRACE(("unregister_domain(%p, %d, %s)\n", _domain, _domain->family,
_domain->name));
net_domain_private* domain = (net_domain_private*)_domain; net_domain_private* domain = (net_domain_private*)_domain;
MutexLocker locker(sDomainLock); MutexLocker locker(sDomainLock);
@@ -361,7 +351,8 @@ unregister_domain(net_domain *_domain)
net_interface_private* interface = NULL; net_interface_private* interface = NULL;
while (true) { while (true) {
interface = (net_interface_private *)list_remove_head_item(&domain->interfaces); interface = (net_interface_private*)list_remove_head_item(
&domain->interfaces);
if (interface == NULL) if (interface == NULL)
break; break;
+74 -97
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright 2006-2007, Haiku, Inc. All Rights Reserved. * Copyright 2006-2009, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
@@ -56,19 +56,16 @@ device_consumer_thread(void *_interface)
break; break;
if (buffer->interface != NULL) { if (buffer->interface != NULL) {
// if the interface is already specified this buffer was // if the interface is already specified, this buffer was
// delivered locally. // delivered locally.
if (buffer->interface->domain->module->receive_data(buffer) == B_OK)
net_domain *domain = buffer->interface->domain;
if (domain->module->receive_data(buffer) == B_OK)
buffer = NULL; buffer = NULL;
} else { } else {
// find handler for this packet // find handler for this packet
DeviceHandlerList::Iterator it2 = DeviceHandlerList::Iterator iterator =
interface->receive_funcs.GetIterator(); interface->receive_funcs.GetIterator();
while (buffer && it2.HasNext()) { while (buffer && iterator.HasNext()) {
net_device_handler *handler = it2.Next(); net_device_handler* handler = iterator.Next();
// if the handler returns B_OK, it consumed the buffer // if the handler returns B_OK, it consumed the buffer
if (handler->type == buffer->type if (handler->type == buffer->type
@@ -77,7 +74,7 @@ device_consumer_thread(void *_interface)
} }
} }
if (buffer) if (buffer != NULL)
gNetBufferModule.free(buffer); gNetBufferModule.free(buffer);
} }
@@ -90,9 +87,7 @@ find_device_interface(const char *name)
{ {
DeviceInterfaceList::Iterator iterator = sInterfaces.GetIterator(); DeviceInterfaceList::Iterator iterator = sInterfaces.GetIterator();
while (iterator.HasNext()) { while (net_device_interface* interface = iterator.Next()) {
net_device_interface *interface = iterator.Next();
if (!strcmp(interface->device->name, name)) if (!strcmp(interface->device->name, name))
return interface; return interface;
} }
@@ -101,6 +96,9 @@ find_device_interface(const char *name)
} }
/*! The domain's device receive handler - this will inject the net_buffers into
the protocol layer (the domain's registered receive handler).
*/
static status_t static status_t
domain_receive_adapter(void* cookie, net_device* device, net_buffer* buffer) domain_receive_adapter(void* cookie, net_device* device, net_buffer* buffer)
{ {
@@ -116,15 +114,15 @@ allocate_device_interface(net_device *device, net_device_module_info *module)
{ {
net_device_interface* interface = new(std::nothrow) net_device_interface; net_device_interface* interface = new(std::nothrow) net_device_interface;
if (interface == NULL) if (interface == NULL)
goto error_0; return NULL;
recursive_lock_init(&interface->rx_lock, "rx lock"); recursive_lock_init(&interface->receive_lock, "interface receive lock");
char name[128]; char name[128];
snprintf(name, sizeof(name), "%s receive queue", device->name); snprintf(name, sizeof(name), "%s receive queue", device->name);
if (init_fifo(&interface->receive_queue, name, 16 * 1024 * 1024) < B_OK) if (init_fifo(&interface->receive_queue, name, 16 * 1024 * 1024) < B_OK)
goto error_2; goto error1;
interface->device = device; interface->device = device;
interface->up_count = 0; interface->up_count = 0;
@@ -138,7 +136,7 @@ allocate_device_interface(net_device *device, net_device_module_info *module)
interface->consumer_thread = spawn_kernel_thread(device_consumer_thread, interface->consumer_thread = spawn_kernel_thread(device_consumer_thread,
name, B_DISPLAY_PRIORITY, interface); name, B_DISPLAY_PRIORITY, interface);
if (interface->consumer_thread < B_OK) if (interface->consumer_thread < B_OK)
goto error_3; goto error2;
resume_thread(interface->consumer_thread); resume_thread(interface->consumer_thread);
// TODO: proper interface index allocation // TODO: proper interface index allocation
@@ -148,20 +146,18 @@ allocate_device_interface(net_device *device, net_device_module_info *module)
sInterfaces.Add(interface); sInterfaces.Add(interface);
return interface; return interface;
error_3: error2:
uninit_fifo(&interface->receive_queue); uninit_fifo(&interface->receive_queue);
error1:
error_2: recursive_lock_destroy(&interface->receive_lock);
recursive_lock_destroy(&interface->rx_lock);
delete interface; delete interface;
error_0:
return NULL; return NULL;
} }
net_device_interface * static net_device_interface*
grab_device_interface(net_device_interface *interface) acquire_device_interface(net_device_interface* interface)
{ {
if (interface == NULL || atomic_add(&interface->ref_count, 1) == 0) if (interface == NULL || atomic_add(&interface->ref_count, 1) == 0)
return NULL; return NULL;
@@ -173,12 +169,10 @@ grab_device_interface(net_device_interface *interface)
static void static void
notify_device_monitors(net_device_interface* interface, int32 event) notify_device_monitors(net_device_interface* interface, int32 event)
{ {
DeviceMonitorList::Iterator iterator = interface->monitor_funcs.GetIterator(); DeviceMonitorList::Iterator iterator
while (iterator.HasNext()) { = interface->monitor_funcs.GetIterator();
// when we call Next() the next item in the list is obtained while (net_device_monitor* monitor = iterator.Next()) {
// so it's safe for the "current" item to remove itself. // it's safe for the "current" item to remove itself.
net_device_monitor *monitor = iterator.Next();
monitor->event(monitor, event); monitor->event(monitor, event);
} }
} }
@@ -187,8 +181,7 @@ notify_device_monitors(net_device_interface *interface, int32 event)
// #pragma mark - interfaces // #pragma mark - interfaces
/*! /*! Searches for a specific interface in a domain by name.
Searches for a specific interface in a domain by name.
You need to have the domain's lock hold when calling this function. You need to have the domain's lock hold when calling this function.
*/ */
struct net_interface_private* struct net_interface_private*
@@ -210,8 +203,7 @@ find_interface(struct net_domain *domain, const char *name)
} }
/*! /*! Searches for a specific interface in a domain by index.
Searches for a specific interface in a domain by index.
You need to have the domain's lock hold when calling this function. You need to have the domain's lock hold when calling this function.
*/ */
struct net_interface_private* struct net_interface_private*
@@ -237,8 +229,7 @@ status_t
create_interface(net_domain* domain, const char* name, const char* baseName, create_interface(net_domain* domain, const char* name, const char* baseName,
net_device_interface* deviceInterface, net_interface_private** _interface) net_device_interface* deviceInterface, net_interface_private** _interface)
{ {
net_interface_private *interface = net_interface_private* interface = new(std::nothrow) net_interface_private;
new (std::nothrow) net_interface_private;
if (interface == NULL) if (interface == NULL)
return B_NO_MEMORY; return B_NO_MEMORY;
@@ -256,7 +247,7 @@ create_interface(net_domain *domain, const char *name, const char *baseName,
interface->type = 0; interface->type = 0;
interface->mtu = deviceInterface->device->mtu; interface->mtu = deviceInterface->device->mtu;
interface->metric = 0; interface->metric = 0;
interface->device_interface = grab_device_interface(deviceInterface); interface->device_interface = acquire_device_interface(deviceInterface);
// setup direct route for bound devices // setup direct route for bound devices
interface->direct_route.destination = NULL; interface->direct_route.destination = NULL;
@@ -402,8 +393,7 @@ count_device_interfaces()
} }
/*! /*! Dumps a list of all interfaces into the supplied userland buffer.
Dumps a list of all interfaces into the supplied userland buffer.
If the interfaces don't fit into the buffer, an error (\c ENOBUFS) is If the interfaces don't fit into the buffer, an error (\c ENOBUFS) is
returned. returned.
*/ */
@@ -415,15 +405,12 @@ list_device_interfaces(void *_buffer, size_t *bufferSize)
DeviceInterfaceList::Iterator iterator = sInterfaces.GetIterator(); DeviceInterfaceList::Iterator iterator = sInterfaces.GetIterator();
UserBuffer buffer(_buffer, *bufferSize); UserBuffer buffer(_buffer, *bufferSize);
while (iterator.HasNext()) { while (net_device_interface* interface = iterator.Next()) {
net_device_interface *interface = iterator.Next();
ifreq request; ifreq request;
strlcpy(request.ifr_name, interface->device->name, IF_NAMESIZE); strlcpy(request.ifr_name, interface->device->name, IF_NAMESIZE);
get_device_interface_address(interface, &request.ifr_addr); get_device_interface_address(interface, &request.ifr_addr);
if (buffer.Copy(&request, IF_NAMESIZE if (buffer.Copy(&request, IF_NAMESIZE + request.ifr_addr.sa_len) == NULL)
+ request.ifr_addr.sa_len) == NULL)
return buffer.Status(); return buffer.Status();
} }
@@ -432,8 +419,7 @@ list_device_interfaces(void *_buffer, size_t *bufferSize)
} }
/*! /*! Releases the reference for the interface. When all references are
Releases the reference for the interface. When all references are
released, the interface is removed. released, the interface is removed.
*/ */
void void
@@ -453,26 +439,25 @@ put_device_interface(struct net_device_interface *interface)
net_device* device = interface->device; net_device* device = interface->device;
const char* moduleName = device->module->info.name; const char* moduleName = device->module->info.name;
device->module->uninit_device(device); device->module->uninit_device(device);
put_module(moduleName); put_module(moduleName);
recursive_lock_destroy(&interface->rx_lock); recursive_lock_destroy(&interface->receive_lock);
delete interface; delete interface;
} }
/*! /*! Finds an interface by the specified index and acquires a reference to it.
Finds an interface by the specified index and grabs a reference to it.
*/ */
struct net_device_interface* struct net_device_interface*
get_device_interface(uint32 index) get_device_interface(uint32 index)
{ {
MutexLocker locker(sInterfaceLock); MutexLocker locker(sInterfaceLock);
// TODO: maintain an array of all device interfaces instead
DeviceInterfaceList::Iterator iterator = sInterfaces.GetIterator(); DeviceInterfaceList::Iterator iterator = sInterfaces.GetIterator();
while (net_device_interface* interface = iterator.Next()) {
while (iterator.HasNext()) {
net_device_interface *interface = iterator.Next();
if (interface->device->index == index) { if (interface->device->index == index) {
if (atomic_add(&interface->ref_count, 1) != 0) if (atomic_add(&interface->ref_count, 1) != 0)
return interface; return interface;
@@ -483,8 +468,7 @@ get_device_interface(uint32 index)
} }
/*! /*! Finds an interface by the specified name and grabs a reference to it.
Finds an interface by the specified name and grabs a reference to it.
If the interface does not yet exist, a new one is created. If the interface does not yet exist, a new one is created.
*/ */
struct net_device_interface* struct net_device_interface*
@@ -521,8 +505,9 @@ get_device_interface(const char *name, bool create)
status_t status = module->init_device(name, &device); status_t status = module->init_device(name, &device);
if (status == B_OK) { if (status == B_OK) {
interface = allocate_device_interface(device, module); interface = allocate_device_interface(device, module);
if (interface) if (interface != NULL)
return interface; return interface;
module->uninit_device(device); module->uninit_device(device);
} }
put_module(moduleName); put_module(moduleName);
@@ -536,7 +521,7 @@ get_device_interface(const char *name, bool create)
void void
down_device_interface(net_device_interface* interface) down_device_interface(net_device_interface* interface)
{ {
// RX lock must be held when calling down_device_interface. // Receive lock must be held when calling down_device_interface.
// Known callers are `interface_protocol_down' which gets // Known callers are `interface_protocol_down' which gets
// here via one of the following paths: // here via one of the following paths:
// //
@@ -557,31 +542,25 @@ down_device_interface(net_device_interface *interface)
notify_device_monitors(interface, B_DEVICE_GOING_DOWN); notify_device_monitors(interface, B_DEVICE_GOING_DOWN);
if (device->module->receive_data != NULL) { if (device->module->receive_data != NULL) {
thread_id reader_thread = interface->reader_thread; thread_id readerThread = interface->reader_thread;
// 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->receive_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(readerThread, &status);
recursive_lock_lock(&interface->rx_lock); recursive_lock_lock(&interface->receive_lock);
} }
} }
// #pragma mark - devices // #pragma mark - devices stack API
/*! /*! Unregisters a previously registered deframer function. */
Unregisters a previously registered deframer function.
This function is part of the net_manager_module_info API.
*/
status_t status_t
unregister_device_deframer(net_device* device) unregister_device_deframer(net_device* device)
{ {
@@ -592,7 +571,7 @@ unregister_device_deframer(net_device *device)
if (interface == NULL) if (interface == NULL)
return ENODEV; return ENODEV;
RecursiveLocker _(interface->rx_lock); RecursiveLocker _(interface->receive_lock);
if (--interface->deframe_ref_count == 0) if (--interface->deframe_ref_count == 0)
interface->deframe_func = NULL; interface->deframe_func = NULL;
@@ -601,15 +580,12 @@ unregister_device_deframer(net_device *device)
} }
/*! /*! Registers the deframer function for the specified \a device.
Registers the deframer function for the specified \a device.
Note, however, that right now, you can only register one single Note, however, that right now, you can only register one single
deframer function per device. deframer function per device.
If the need arises, we might want to lift that limitation at a If the need arises, we might want to lift that limitation at a
later time (which would require a slight API change, though). later time (which would require a slight API change, though).
This function is part of the net_manager_module_info API.
*/ */
status_t status_t
register_device_deframer(net_device* device, net_deframe_func deframeFunc) register_device_deframer(net_device* device, net_deframe_func deframeFunc)
@@ -621,9 +597,10 @@ register_device_deframer(net_device *device, net_deframe_func deframeFunc)
if (interface == NULL) if (interface == NULL)
return ENODEV; return ENODEV;
RecursiveLocker _(interface->rx_lock); RecursiveLocker _(interface->receive_lock);
if (interface->deframe_func != NULL && interface->deframe_func != deframeFunc) if (interface->deframe_func != NULL
&& interface->deframe_func != deframeFunc)
return B_ERROR; return B_ERROR;
interface->deframe_func = deframeFunc; interface->deframe_func = deframeFunc;
@@ -632,6 +609,7 @@ register_device_deframer(net_device *device, net_deframe_func deframeFunc)
} }
/*! Registers a domain to receive net_buffers from the specified \a device. */
status_t status_t
register_domain_device_handler(struct net_device* device, int32 type, register_domain_device_handler(struct net_device* device, int32 type,
struct net_domain* _domain) struct net_domain* _domain)
@@ -640,10 +618,12 @@ register_domain_device_handler(struct net_device *device, int32 type,
if (domain->module == NULL || domain->module->receive_data == NULL) if (domain->module == NULL || domain->module->receive_data == NULL)
return B_BAD_VALUE; return B_BAD_VALUE;
return register_device_handler(device, type, &domain_receive_adapter, domain); return register_device_handler(device, type, &domain_receive_adapter,
domain);
} }
/*! Registers a receiving function callback for the specified \a device. */
status_t status_t
register_device_handler(struct net_device* device, int32 type, register_device_handler(struct net_device* device, int32 type,
net_receive_func receiveFunc, void* cookie) net_receive_func receiveFunc, void* cookie)
@@ -655,14 +635,13 @@ register_device_handler(struct net_device *device, int32 type,
if (interface == NULL) if (interface == NULL)
return ENODEV; return ENODEV;
RecursiveLocker _(interface->rx_lock); RecursiveLocker _(interface->receive_lock);
// see if such a handler already for this device // see if such a handler already for this device
DeviceHandlerList::Iterator iterator = interface->receive_funcs.GetIterator(); DeviceHandlerList::Iterator iterator
while (iterator.HasNext()) { = interface->receive_funcs.GetIterator();
net_device_handler *handler = iterator.Next(); while (net_device_handler* handler = iterator.Next()) {
if (handler->type == type) if (handler->type == type)
return B_ERROR; return B_ERROR;
} }
@@ -681,6 +660,7 @@ register_device_handler(struct net_device *device, int32 type,
} }
/*! Unregisters a previously registered device handler. */
status_t status_t
unregister_device_handler(struct net_device* device, int32 type) unregister_device_handler(struct net_device* device, int32 type)
{ {
@@ -691,14 +671,13 @@ unregister_device_handler(struct net_device *device, int32 type)
if (interface == NULL) if (interface == NULL)
return ENODEV; return ENODEV;
RecursiveLocker _(interface->rx_lock); RecursiveLocker _(interface->receive_lock);
// search for the handler // search for the handler
DeviceHandlerList::Iterator iterator = interface->receive_funcs.GetIterator(); DeviceHandlerList::Iterator iterator
while (iterator.HasNext()) { = interface->receive_funcs.GetIterator();
net_device_handler *handler = iterator.Next(); while (net_device_handler* handler = iterator.Next()) {
if (handler->type == type) { if (handler->type == type) {
// found it // found it
iterator.Remove(); iterator.Remove();
@@ -711,6 +690,7 @@ unregister_device_handler(struct net_device *device, int32 type)
} }
/*! Registers a device monitor for the specified device. */
status_t status_t
register_device_monitor(net_device* device, net_device_monitor* monitor) register_device_monitor(net_device* device, net_device_monitor* monitor)
{ {
@@ -724,12 +704,13 @@ register_device_monitor(net_device *device, net_device_monitor *monitor)
if (interface == NULL) if (interface == NULL)
return ENODEV; return ENODEV;
RecursiveLocker _(interface->rx_lock); RecursiveLocker _(interface->receive_lock);
interface->monitor_funcs.Add(monitor); interface->monitor_funcs.Add(monitor);
return B_OK; return B_OK;
} }
/*! Unregisters a previously registered device monitor. */
status_t status_t
unregister_device_monitor(net_device* device, net_device_monitor* monitor) unregister_device_monitor(net_device* device, net_device_monitor* monitor)
{ {
@@ -740,7 +721,7 @@ unregister_device_monitor(net_device *device, net_device_monitor *monitor)
if (interface == NULL) if (interface == NULL)
return ENODEV; return ENODEV;
RecursiveLocker _(interface->rx_lock); RecursiveLocker _(interface->receive_lock);
// search for the monitor // search for the monitor
@@ -756,8 +737,7 @@ unregister_device_monitor(net_device *device, net_device_monitor *monitor)
} }
/*! /*! This function is called by device modules in case their link
This function is called by device modules in case their link
state changed, ie. if an ethernet cable was plugged in or state changed, ie. if an ethernet cable was plugged in or
removed. removed.
*/ */
@@ -769,10 +749,8 @@ device_link_changed(net_device *device)
} }
/*! /*! This function is called by device modules once their device got
This function is called by device modules once their device got
physically removed, ie. a USB networking card is unplugged. physically removed, ie. a USB networking card is unplugged.
It is part of the net_manager_module_info API.
*/ */
status_t status_t
device_removed(net_device* device) device_removed(net_device* device)
@@ -789,7 +767,7 @@ device_removed(net_device *device)
// This is very complex, refer to delete_interface() for // This is very complex, refer to delete_interface() for
// further details. // further details.
RecursiveLocker _(interface->rx_lock); RecursiveLocker _(interface->receive_lock);
// this will possibly call: // this will possibly call:
// remove_interface_from_domain() [domain gets locked] // remove_interface_from_domain() [domain gets locked]
@@ -804,7 +782,7 @@ device_removed(net_device *device)
interface->monitor_funcs.RemoveAll(); interface->monitor_funcs.RemoveAll();
// All of the readers should be gone as well since we are out of // All of the readers should be gone as well since we are out of
// interfaces and `put_domain_datalink_protocols' is called for // interfaces and put_domain_datalink_protocols() is called for
// each delete_interface(). // each delete_interface().
put_device_interface(interface); put_device_interface(interface);
@@ -817,7 +795,6 @@ status_t
device_enqueue_buffer(net_device* device, net_buffer* buffer) device_enqueue_buffer(net_device* device, net_buffer* buffer)
{ {
net_device_interface* interface = get_device_interface(device->index); net_device_interface* interface = get_device_interface(device->index);
if (interface == NULL) if (interface == NULL)
return ENODEV; return ENODEV;
@@ -1,5 +1,5 @@
/* /*
* Copyright 2006-2007, Haiku, Inc. All Rights Reserved. * Copyright 2006-2009, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
@@ -39,7 +39,7 @@ struct net_device_interface : DoublyLinkedListLinkImpl<net_device_interface> {
DeviceMonitorList monitor_funcs; DeviceMonitorList monitor_funcs;
DeviceHandlerList receive_funcs; DeviceHandlerList receive_funcs;
recursive_lock rx_lock; recursive_lock receive_lock;
thread_id consumer_thread; thread_id consumer_thread;
net_fifo receive_queue; net_fifo receive_queue;
@@ -69,7 +69,7 @@ status_t create_interface(net_domain *domain, const char *name,
const char* baseName, net_device_interface* deviceInterface, const char* baseName, net_device_interface* deviceInterface,
struct net_interface_private** _interface); struct net_interface_private** _interface);
void delete_interface(net_interface_private* interface); void delete_interface(net_interface_private* interface);
void interface_set_down(net_interface *); void interface_set_down(net_interface* interface);
// device interfaces // device interfaces
void get_device_interface_address(net_device_interface* interface, void get_device_interface_address(net_device_interface* interface,