1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-22 17:35:59 +03:00

dmeventd thread/fifo fixes.

This commit is contained in:
Alasdair Kergon 2006-03-09 21:33:59 +00:00
parent 4cf7a108e8
commit 5d02f60bde
2 changed files with 42 additions and 26 deletions

View File

@ -1,5 +1,6 @@
Version 1.02.04 -
============================
dmeventd thread/fifo fixes.
Add file & line to dm_strdup_aux().
Add setgeometry.

View File

@ -1032,21 +1032,32 @@ static int open_fifos(struct dm_event_fifos *fifos)
/*
* Read message from client making sure that data is available
* and a complete message is read.
* and a complete message is read. Must not block indefinitely.
*/
static int client_read(struct dm_event_fifos *fifos, struct dm_event_daemon_message *msg)
{
struct timeval t;
unsigned bytes = 0;
int ret = 0;
fd_set fds;
errno = 0;
while (bytes < sizeof(*msg) && errno != EOF) {
do {
/* Watch client read FIFO for input. */
FD_ZERO(&fds);
FD_SET(fifos->client, &fds);
} while (select(fifos->client+1, &fds, NULL, NULL, NULL) != 1);
/* Watch client read FIFO for input. */
FD_ZERO(&fds);
FD_SET(fifos->client, &fds);
t.tv_sec = 1;
t.tv_usec = 0;
ret = select(fifos->client+1, &fds, NULL, NULL, &t);
if (!ret && !bytes) /* nothing to read */
return 0;
if (!ret) /* trying to finish read */
continue;
if (ret < 0) /* error */
return 0;
ret = read(fifos->client, msg, sizeof(*msg) - bytes);
bytes += ret > 0 ? ret : 0;
@ -1138,12 +1149,16 @@ static void process_request(struct dm_event_fifos *fifos)
/* FIXME: better error handling */
/* Read the request from the client. */
if (!memset(&msg, 0, sizeof(msg)) ||
!client_read(fifos, &msg)) {
stack;
memset(&msg, 0, sizeof(msg));
/*
* Read the request from the client.
* Of course, it's tough to tell what to do when
* we use fucking retarded return codes like
* 0 for error.
*/
if (!client_read(fifos, &msg))
return;
}
msg.opcode.status = do_process_request(&msg);
@ -1276,25 +1291,25 @@ void dmeventd(void)
/*
* We exit when there are no more devices to watch.
* That is, when the last unregister happens.
*
* We must be careful though. One of our threads which is
* watching a device may receive an event and:
* 1) Alter the device and unregister it
* or
* 2) Alter the device, unregister, [alter again,] and reregister
*
* We must be capable of answering a request to unregister
* that comes from the very thread that must be unregistered.
* Additionally, if that thread unregisters itself and it was the
* only thread being monitored, we must also handle the case where
* that thread may perform a register before exiting. (In other
* words, we can not simply exit if all threads have been unregistered
* unless all threads are done processing.
*/
do {
process_request(&fifos);
cleanup_unused_threads();
} while(!list_empty(&thread_registry));
/*
* There may still have been some threads that were doing work,
* make sure these are cleaned up
*
* I don't necessarily like the sleep there, but otherwise,
* cleanup_unused_threads could get called many many times.
* It's worth noting that the likelyhood of it being called
* here is slim.
*/
while(!list_empty(&thread_registry_unused)) {
sleep(1);
cleanup_unused_threads();
}
} while(!list_empty(&thread_registry) || !list_empty(&thread_registry_unused));
exit_dm_lib();