Changed the FD selection/deselection handling a bit:
* B_EVENT_INVALID is no longer passed to the FD's select()/deselect() hooks. * Now we always attach the select info to the I/O context, even if no event has been selected. The reasoning is that B_EVENT_INVALID is always automatically selected and handled by the VFS, so we need the handle to notify on close(). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@32417 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
+15
-19
@@ -1,4 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
|
* Copyright 2009, Ingo Weinhold, [email protected].
|
||||||
* Copyright 2002-2009, Axel Dörfler, [email protected].
|
* Copyright 2002-2009, Axel Dörfler, [email protected].
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
@@ -522,9 +523,10 @@ deselect_select_infos(file_descriptor* descriptor, select_info* infos)
|
|||||||
select_sync* sync = info->sync;
|
select_sync* sync = info->sync;
|
||||||
|
|
||||||
// deselect the selected events
|
// deselect the selected events
|
||||||
if (descriptor->ops->fd_deselect && info->selected_events) {
|
uint16 eventsToDeselect = info->selected_events & ~B_EVENT_INVALID;
|
||||||
|
if (descriptor->ops->fd_deselect != NULL && eventsToDeselect != 0) {
|
||||||
for (uint16 event = 1; event < 16; event++) {
|
for (uint16 event = 1; event < 16; event++) {
|
||||||
if (info->selected_events & SELECT_FLAG(event)) {
|
if ((eventsToDeselect & SELECT_FLAG(event)) != 0) {
|
||||||
descriptor->ops->fd_deselect(descriptor, event,
|
descriptor->ops->fd_deselect(descriptor, event,
|
||||||
(selectsync*)info);
|
(selectsync*)info);
|
||||||
}
|
}
|
||||||
@@ -554,13 +556,12 @@ select_fd(int32 fd, struct select_info* info, bool kernel)
|
|||||||
if (descriptor == NULL)
|
if (descriptor == NULL)
|
||||||
return B_FILE_ERROR;
|
return B_FILE_ERROR;
|
||||||
|
|
||||||
if (info->selected_events == 0)
|
uint16 eventsToSelect = info->selected_events & ~B_EVENT_INVALID;
|
||||||
return B_OK;
|
|
||||||
|
|
||||||
if (!descriptor->ops->fd_select) {
|
if (descriptor->ops->fd_select == NULL && eventsToSelect != 0) {
|
||||||
// if the I/O subsystem doesn't support select(), we will
|
// if the I/O subsystem doesn't support select(), we will
|
||||||
// immediately notify the select call
|
// immediately notify the select call
|
||||||
return notify_select_events(info, info->selected_events);
|
return notify_select_events(info, eventsToSelect);
|
||||||
}
|
}
|
||||||
|
|
||||||
// We need the FD to stay open while we're doing this, so no select()/
|
// We need the FD to stay open while we're doing this, so no select()/
|
||||||
@@ -573,16 +574,17 @@ select_fd(int32 fd, struct select_info* info, bool kernel)
|
|||||||
uint32 selectedEvents = 0;
|
uint32 selectedEvents = 0;
|
||||||
|
|
||||||
for (uint16 event = 1; event < 16; event++) {
|
for (uint16 event = 1; event < 16; event++) {
|
||||||
if (info->selected_events & SELECT_FLAG(event)
|
if ((eventsToSelect & SELECT_FLAG(event)) != 0
|
||||||
&& descriptor->ops->fd_select(descriptor, event,
|
&& descriptor->ops->fd_select(descriptor, event,
|
||||||
(selectsync*)info) == B_OK) {
|
(selectsync*)info) == B_OK) {
|
||||||
selectedEvents |= SELECT_FLAG(event);
|
selectedEvents |= SELECT_FLAG(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
info->selected_events = selectedEvents;
|
info->selected_events = selectedEvents
|
||||||
|
| (info->selected_events & B_EVENT_INVALID);
|
||||||
|
|
||||||
// If any event has been selected, add the info to the IO context.
|
// Add the info to the IO context. Even if nothing has been selected -- we
|
||||||
if (selectedEvents != 0) {
|
// always support B_EVENT_INVALID.
|
||||||
locker.Lock();
|
locker.Lock();
|
||||||
if (context->fds[fd] != descriptor) {
|
if (context->fds[fd] != descriptor) {
|
||||||
// Someone close()d the index in the meantime. deselect() all
|
// Someone close()d the index in the meantime. deselect() all
|
||||||
@@ -608,10 +610,6 @@ select_fd(int32 fd, struct select_info* info, bool kernel)
|
|||||||
// since as long as the descriptor is associated with the slot,
|
// since as long as the descriptor is associated with the slot,
|
||||||
// someone else still has it open.
|
// someone else still has it open.
|
||||||
atomic_add(&descriptor->open_count, -1);
|
atomic_add(&descriptor->open_count, -1);
|
||||||
} else {
|
|
||||||
// Release our open reference.
|
|
||||||
close_fd(descriptor);
|
|
||||||
}
|
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@@ -623,9 +621,6 @@ deselect_fd(int32 fd, struct select_info* info, bool kernel)
|
|||||||
TRACE(("deselect_fd(fd = %ld, info = %p (%p), 0x%x)\n", fd, info,
|
TRACE(("deselect_fd(fd = %ld, info = %p (%p), 0x%x)\n", fd, info,
|
||||||
info->sync, info->selected_events));
|
info->sync, info->selected_events));
|
||||||
|
|
||||||
if (info->selected_events == 0)
|
|
||||||
return B_OK;
|
|
||||||
|
|
||||||
FDGetter fdGetter;
|
FDGetter fdGetter;
|
||||||
// define before the context locker, so it will be destroyed after it
|
// define before the context locker, so it will be destroyed after it
|
||||||
|
|
||||||
@@ -651,9 +646,10 @@ deselect_fd(int32 fd, struct select_info* info, bool kernel)
|
|||||||
locker.Unlock();
|
locker.Unlock();
|
||||||
|
|
||||||
// deselect the selected events
|
// deselect the selected events
|
||||||
if (descriptor->ops->fd_deselect && info->selected_events) {
|
uint16 eventsToDeselect = info->selected_events & ~B_EVENT_INVALID;
|
||||||
|
if (descriptor->ops->fd_deselect != NULL && eventsToDeselect != 0) {
|
||||||
for (uint16 event = 1; event < 16; event++) {
|
for (uint16 event = 1; event < 16; event++) {
|
||||||
if (info->selected_events & SELECT_FLAG(event)) {
|
if ((eventsToDeselect & SELECT_FLAG(event)) != 0) {
|
||||||
descriptor->ops->fd_deselect(descriptor, event,
|
descriptor->ops->fd_deselect(descriptor, event,
|
||||||
(selectsync*)info);
|
(selectsync*)info);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user