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:
parent
5ce6cb5c32
commit
57dc0e2a53
@ -1,4 +1,5 @@
|
||||
/*
|
||||
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||
* Copyright 2002-2009, Axel Dörfler, axeld@pinc-software.de.
|
||||
* 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;
|
||||
|
||||
// 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++) {
|
||||
if (info->selected_events & SELECT_FLAG(event)) {
|
||||
if ((eventsToDeselect & SELECT_FLAG(event)) != 0) {
|
||||
descriptor->ops->fd_deselect(descriptor, event,
|
||||
(selectsync*)info);
|
||||
}
|
||||
@ -554,13 +556,12 @@ select_fd(int32 fd, struct select_info* info, bool kernel)
|
||||
if (descriptor == NULL)
|
||||
return B_FILE_ERROR;
|
||||
|
||||
if (info->selected_events == 0)
|
||||
return B_OK;
|
||||
uint16 eventsToSelect = info->selected_events & ~B_EVENT_INVALID;
|
||||
|
||||
if (!descriptor->ops->fd_select) {
|
||||
if (descriptor->ops->fd_select == NULL && eventsToSelect != 0) {
|
||||
// if the I/O subsystem doesn't support select(), we will
|
||||
// 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()/
|
||||
@ -573,46 +574,43 @@ select_fd(int32 fd, struct select_info* info, bool kernel)
|
||||
uint32 selectedEvents = 0;
|
||||
|
||||
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,
|
||||
(selectsync*)info) == B_OK) {
|
||||
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.
|
||||
if (selectedEvents != 0) {
|
||||
locker.Lock();
|
||||
if (context->fds[fd] != descriptor) {
|
||||
// Someone close()d the index in the meantime. deselect() all
|
||||
// events.
|
||||
info->next = NULL;
|
||||
deselect_select_infos(descriptor, info);
|
||||
// Add the info to the IO context. Even if nothing has been selected -- we
|
||||
// always support B_EVENT_INVALID.
|
||||
locker.Lock();
|
||||
if (context->fds[fd] != descriptor) {
|
||||
// Someone close()d the index in the meantime. deselect() all
|
||||
// events.
|
||||
info->next = NULL;
|
||||
deselect_select_infos(descriptor, info);
|
||||
|
||||
// Release our open reference of the descriptor.
|
||||
close_fd(descriptor);
|
||||
return B_FILE_ERROR;
|
||||
}
|
||||
|
||||
// The FD index hasn't changed, so we add the select info to the table.
|
||||
|
||||
info->next = context->select_infos[fd];
|
||||
context->select_infos[fd] = info;
|
||||
|
||||
// As long as the info is in the list, we keep a reference to the sync
|
||||
// object.
|
||||
atomic_add(&info->sync->ref_count, 1);
|
||||
|
||||
// Finally release our open reference. It is safe just to decrement,
|
||||
// since as long as the descriptor is associated with the slot,
|
||||
// someone else still has it open.
|
||||
atomic_add(&descriptor->open_count, -1);
|
||||
} else {
|
||||
// Release our open reference.
|
||||
// Release our open reference of the descriptor.
|
||||
close_fd(descriptor);
|
||||
return B_FILE_ERROR;
|
||||
}
|
||||
|
||||
// The FD index hasn't changed, so we add the select info to the table.
|
||||
|
||||
info->next = context->select_infos[fd];
|
||||
context->select_infos[fd] = info;
|
||||
|
||||
// As long as the info is in the list, we keep a reference to the sync
|
||||
// object.
|
||||
atomic_add(&info->sync->ref_count, 1);
|
||||
|
||||
// Finally release our open reference. It is safe just to decrement,
|
||||
// since as long as the descriptor is associated with the slot,
|
||||
// someone else still has it open.
|
||||
atomic_add(&descriptor->open_count, -1);
|
||||
|
||||
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,
|
||||
info->sync, info->selected_events));
|
||||
|
||||
if (info->selected_events == 0)
|
||||
return B_OK;
|
||||
|
||||
FDGetter fdGetter;
|
||||
// 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();
|
||||
|
||||
// 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++) {
|
||||
if (info->selected_events & SELECT_FLAG(event)) {
|
||||
if ((eventsToDeselect & SELECT_FLAG(event)) != 0) {
|
||||
descriptor->ops->fd_deselect(descriptor, event,
|
||||
(selectsync*)info);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user