whenever an interface is deleted, call put_domain_datalink_protocols() so all readers are unregistered.
- Unfortunely this requires RX lock to become a recursive lock. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20621 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
eaf517212a
commit
6473469039
|
@ -45,7 +45,7 @@ device_reader_thread(void *_interface)
|
|||
net_device *device = interface->device;
|
||||
status_t status = B_OK;
|
||||
|
||||
BenaphoreLocker rx_lock(interface->rx_lock);
|
||||
RecursiveLocker rx_lock(interface->rx_lock);
|
||||
|
||||
while (device->flags & IFF_UP) {
|
||||
net_buffer *buffer;
|
||||
|
|
|
@ -213,7 +213,7 @@ domain_interface_control(net_domain_private *domain, int32 option,
|
|||
// and domain locks are required, we MUST obtain the RX
|
||||
// lock before the domain lock. This order MUST NOT ever
|
||||
// be reversed under the penalty of deadlock.
|
||||
BenaphoreLocker _1(device->rx_lock);
|
||||
RecursiveLocker _1(device->rx_lock);
|
||||
BenaphoreLocker _2(domain->lock);
|
||||
|
||||
net_interface *interface = find_interface(domain, name);
|
||||
|
|
|
@ -190,6 +190,12 @@ delete_interface(net_interface_private *interface)
|
|||
// down_device_interface() -- if upcount reaches 0
|
||||
interface_set_down(interface);
|
||||
|
||||
// This call requires the RX Lock to be a recursive
|
||||
// lock since each uninit_protocol() call may call
|
||||
// again into the stack to unregister a reader for
|
||||
// instance, which tries to obtain the RX lock again.
|
||||
put_domain_datalink_protocols(interface);
|
||||
|
||||
put_device_interface(interface->device_interface);
|
||||
|
||||
free(interface->address);
|
||||
|
@ -325,7 +331,7 @@ put_device_interface(struct net_device_interface *interface)
|
|||
interface->module->uninit_device(interface->device);
|
||||
put_module(interface->module->info.name);
|
||||
|
||||
benaphore_destroy(&interface->rx_lock);
|
||||
recursive_lock_destroy(&interface->rx_lock);
|
||||
delete interface;
|
||||
}
|
||||
|
||||
|
@ -392,7 +398,8 @@ get_device_interface(const char *name, bool create)
|
|||
// create new module interface for this
|
||||
interface = new (std::nothrow) net_device_interface;
|
||||
if (interface != NULL) {
|
||||
if (benaphore_init(&interface->rx_lock, "rx lock") >= B_OK) {
|
||||
if (recursive_lock_init(&interface->rx_lock,
|
||||
"rx lock") >= B_OK) {
|
||||
interface->name = device->name;
|
||||
interface->module = module;
|
||||
interface->device = device;
|
||||
|
@ -446,13 +453,13 @@ down_device_interface(net_device_interface *interface)
|
|||
|
||||
// one of the callers must hold a reference to the net_device_interface
|
||||
// usually it is one of the net_interfaces.
|
||||
benaphore_unlock(&interface->rx_lock);
|
||||
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);
|
||||
|
||||
benaphore_lock(&interface->rx_lock);
|
||||
recursive_lock_lock(&interface->rx_lock);
|
||||
}
|
||||
|
||||
|
||||
|
@ -473,7 +480,7 @@ unregister_device_deframer(net_device *device)
|
|||
if (interface == NULL)
|
||||
return ENODEV;
|
||||
|
||||
BenaphoreLocker _(interface->rx_lock);
|
||||
RecursiveLocker _(interface->rx_lock);
|
||||
|
||||
if (--interface->deframe_ref_count == 0)
|
||||
interface->deframe_func = NULL;
|
||||
|
@ -502,7 +509,7 @@ register_device_deframer(net_device *device, net_deframe_func deframeFunc)
|
|||
if (interface == NULL)
|
||||
return ENODEV;
|
||||
|
||||
BenaphoreLocker _(interface->rx_lock);
|
||||
RecursiveLocker _(interface->rx_lock);
|
||||
|
||||
if (interface->deframe_func != NULL && interface->deframe_func != deframeFunc)
|
||||
return B_ERROR;
|
||||
|
@ -536,7 +543,7 @@ register_device_handler(struct net_device *device, int32 type,
|
|||
if (interface == NULL)
|
||||
return ENODEV;
|
||||
|
||||
BenaphoreLocker _(interface->rx_lock);
|
||||
RecursiveLocker _(interface->rx_lock);
|
||||
|
||||
// see if such a handler already for this device
|
||||
|
||||
|
@ -572,7 +579,7 @@ unregister_device_handler(struct net_device *device, int32 type)
|
|||
if (interface == NULL)
|
||||
return ENODEV;
|
||||
|
||||
BenaphoreLocker _(interface->rx_lock);
|
||||
RecursiveLocker _(interface->rx_lock);
|
||||
|
||||
// search for the handler
|
||||
|
||||
|
@ -605,7 +612,7 @@ register_device_monitor(net_device *device, net_device_monitor *monitor)
|
|||
if (interface == NULL)
|
||||
return ENODEV;
|
||||
|
||||
BenaphoreLocker _(interface->rx_lock);
|
||||
RecursiveLocker _(interface->rx_lock);
|
||||
interface->monitor_funcs.Add(monitor);
|
||||
return B_OK;
|
||||
}
|
||||
|
@ -621,7 +628,7 @@ unregister_device_monitor(net_device *device, net_device_monitor *monitor)
|
|||
if (interface == NULL)
|
||||
return ENODEV;
|
||||
|
||||
BenaphoreLocker _(interface->rx_lock);
|
||||
RecursiveLocker _(interface->rx_lock);
|
||||
|
||||
// search for the monitor
|
||||
|
||||
|
@ -669,7 +676,7 @@ device_removed(net_device *device)
|
|||
// This is very complex, refer to delete_interface() for
|
||||
// further details.
|
||||
|
||||
BenaphoreLocker _(interface->rx_lock);
|
||||
RecursiveLocker _(interface->rx_lock);
|
||||
|
||||
// this will possibly call:
|
||||
// remove_interface_from_domain() [domain gets locked]
|
||||
|
@ -690,7 +697,9 @@ device_removed(net_device *device)
|
|||
// didn't, they'll probably wait forever to be callback'ed again.
|
||||
interface->monitor_funcs.RemoveAll();
|
||||
|
||||
// TODO: make sure all readers are gone
|
||||
// All of the readers should be gone as well since we are out of
|
||||
// interfaces and `put_domain_datalink_protocols' is called for
|
||||
// each delete_interface().
|
||||
|
||||
put_device_interface(interface);
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ struct net_device_interface : DoublyLinkedListLinkImpl<net_device_interface> {
|
|||
DeviceMonitorList monitor_funcs;
|
||||
DeviceHandlerList receive_funcs;
|
||||
|
||||
benaphore rx_lock;
|
||||
recursive_lock rx_lock;
|
||||
};
|
||||
|
||||
typedef DoublyLinkedList<net_device_interface> DeviceInterfaceList;
|
||||
|
|
Loading…
Reference in New Issue