- made 'active' variable volatile
Bugfixes:
- fixed deletion of mouse_device from fDevices list when the object is deleted.
- removed deadlock from RemoveDevice
- call UnregisterDevice from inside RemoveDevice
- terminate devicer watcher thread on read error
- skip "serial" directory always
- close file handle when initializing device watcher thread fails


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@16927 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Marcus Overhagen 2006-03-29 22:44:58 +00:00
parent dbb98f2b76
commit d323bbb26f

View File

@ -69,7 +69,7 @@ struct mouse_device {
int fd; int fd;
thread_id device_watcher; thread_id device_watcher;
mouse_settings settings; mouse_settings settings;
bool active; volatile bool active;
}; };
@ -109,8 +109,9 @@ MouseInputDevice::~MouseInputDevice()
StopMonitoringDevice(kMouseDevicesDirectoryUSB); StopMonitoringDevice(kMouseDevicesDirectoryUSB);
StopMonitoringDevice(kMouseDevicesDirectoryPS2); StopMonitoringDevice(kMouseDevicesDirectoryPS2);
for (int32 i = 0; i < fDevices.CountItems(); i++) int count = fDevices.CountItems();
delete (mouse_device *)fDevices.ItemAt(i); while (count-- > 0)
delete (mouse_device *)fDevices.RemoveItem((int32)0);
#if DEBUG #if DEBUG
fclose(sLogFile); fclose(sLogFile);
@ -179,12 +180,13 @@ MouseInputDevice::Start(const char *name, void *cookie)
device->fd = open(device->path, O_RDWR); device->fd = open(device->path, O_RDWR);
if (device->fd < 0) if (device->fd < 0)
return device->fd; return B_ERROR;
status_t status = InitFromSettings(device); status_t status = InitFromSettings(device);
if (status < B_OK) { if (status < B_OK) {
LOG_ERR("%s: can't initialize from settings: %s\n", LOG_ERR("%s: can't initialize from settings: %s\n",
name, strerror(status)); name, strerror(status));
close(device->fd);
return status; return status;
} }
@ -200,6 +202,7 @@ MouseInputDevice::Start(const char *name, void *cookie)
if (device->device_watcher < B_OK) { if (device->device_watcher < B_OK) {
LOG_ERR("%s: can't spawn watching thread: %s\n", LOG_ERR("%s: can't spawn watching thread: %s\n",
name, strerror(device->device_watcher)); name, strerror(device->device_watcher));
close(device->fd);
return device->device_watcher; return device->device_watcher;
} }
@ -207,6 +210,8 @@ MouseInputDevice::Start(const char *name, void *cookie)
if (status < B_OK) { if (status < B_OK) {
LOG_ERR("%s: can't resume watching thread: %s\n", LOG_ERR("%s: can't resume watching thread: %s\n",
name, strerror(status)); name, strerror(status));
kill_thread(device->device_watcher);
close(device->fd);
return status; return status;
} }
@ -221,18 +226,17 @@ MouseInputDevice::Stop(const char *name, void *cookie)
LOG("%s(%s)\n", __PRETTY_FUNCTION__, name); LOG("%s(%s)\n", __PRETTY_FUNCTION__, name);
close(device->fd);
device->active = false; device->active = false;
if (device->device_watcher >= 0) { if (device->device_watcher >= 0) {
// TODO: This is done to unblock the thread, // unblock the thread, which is waiting on a semaphore.
// which is waiting on a semaphore.
suspend_thread(device->device_watcher); suspend_thread(device->device_watcher);
resume_thread(device->device_watcher); resume_thread(device->device_watcher);
status_t dummy; status_t dummy;
wait_for_thread(device->device_watcher, &dummy); wait_for_thread(device->device_watcher, &dummy);
} }
close(device->fd);
return B_OK; return B_OK;
} }
@ -321,11 +325,16 @@ status_t
MouseInputDevice::RemoveDevice(const char *path) MouseInputDevice::RemoveDevice(const char *path)
{ {
CALLED(); CALLED();
int32 i = 0; mouse_device *device;
mouse_device *device = NULL; for (int i = 0; (device = (mouse_device *)fDevices.ItemAt(i)) != NULL; i++) {
while ((device = (mouse_device *)fDevices.ItemAt(i)) != NULL) {
if (!strcmp(device->path, path)) { if (!strcmp(device->path, path)) {
fDevices.RemoveItem(device); fDevices.RemoveItem(device);
input_device_ref *devices[2];
devices[0] = &device->device_ref;
devices[1] = NULL;
UnregisterDevices(devices);
delete device; delete device;
return B_OK; return B_OK;
} }
@ -352,8 +361,7 @@ MouseInputDevice::DeviceWatcher(mouse_device *dev)
while (dev->active) { while (dev->active) {
memset(&movements, 0, sizeof(movements)); memset(&movements, 0, sizeof(movements));
if (ioctl(dev->fd, MS_READ, &movements) != B_OK) { if (ioctl(dev->fd, MS_READ, &movements) != B_OK) {
snooze(10000); // this is a realtime thread, and something is wrong... return 0;
continue;
} }
uint32 buttons = buttons_state ^ movements.buttons; uint32 buttons = buttons_state ^ movements.buttons;
@ -419,19 +427,14 @@ MouseInputDevice::RecursiveScan(const char *directory)
{ {
CALLED(); CALLED();
bool found_ps2 = false;
BEntry entry; BEntry entry;
BDirectory dir(directory); BDirectory dir(directory);
while (dir.GetNextEntry(&entry) == B_OK) { while (dir.GetNextEntry(&entry) == B_OK) {
BPath path; BPath path;
entry.GetPath(&path); entry.GetPath(&path);
char name[B_FILE_NAME_LENGTH]; if (0 == strcmp(path.Leaf(), "serial"))
entry.GetName(name); continue; // skip serial
if (strcmp(name, "ps2") == 0)
found_ps2 = true;
if (strcmp(name,"serial") == 0 && found_ps2)
continue;
if (entry.IsDirectory()) if (entry.IsDirectory())
RecursiveScan(path.Path()); RecursiveScan(path.Path());