mirror of
git://sourceware.org/git/lvm2.git
synced 2024-10-27 01:55:10 +03:00
dmeventd thread/fifo fixes.
This commit is contained in:
parent
d6207798e6
commit
9ab7701215
@ -1,5 +1,6 @@
|
|||||||
Version 1.02.04 -
|
Version 1.02.04 -
|
||||||
============================
|
============================
|
||||||
|
dmeventd thread/fifo fixes.
|
||||||
Add file & line to dm_strdup_aux().
|
Add file & line to dm_strdup_aux().
|
||||||
Add setgeometry.
|
Add setgeometry.
|
||||||
|
|
||||||
|
@ -1032,21 +1032,32 @@ static int open_fifos(struct dm_event_fifos *fifos)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Read message from client making sure that data is available
|
* 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)
|
static int client_read(struct dm_event_fifos *fifos, struct dm_event_daemon_message *msg)
|
||||||
{
|
{
|
||||||
|
struct timeval t;
|
||||||
unsigned bytes = 0;
|
unsigned bytes = 0;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
fd_set fds;
|
fd_set fds;
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
while (bytes < sizeof(*msg) && errno != EOF) {
|
while (bytes < sizeof(*msg) && errno != EOF) {
|
||||||
do {
|
/* Watch client read FIFO for input. */
|
||||||
/* Watch client read FIFO for input. */
|
FD_ZERO(&fds);
|
||||||
FD_ZERO(&fds);
|
FD_SET(fifos->client, &fds);
|
||||||
FD_SET(fifos->client, &fds);
|
t.tv_sec = 1;
|
||||||
} while (select(fifos->client+1, &fds, NULL, NULL, NULL) != 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);
|
ret = read(fifos->client, msg, sizeof(*msg) - bytes);
|
||||||
bytes += ret > 0 ? ret : 0;
|
bytes += ret > 0 ? ret : 0;
|
||||||
@ -1138,12 +1149,16 @@ static void process_request(struct dm_event_fifos *fifos)
|
|||||||
|
|
||||||
/* FIXME: better error handling */
|
/* FIXME: better error handling */
|
||||||
|
|
||||||
/* Read the request from the client. */
|
memset(&msg, 0, sizeof(msg));
|
||||||
if (!memset(&msg, 0, sizeof(msg)) ||
|
|
||||||
!client_read(fifos, &msg)) {
|
/*
|
||||||
stack;
|
* 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;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
msg.opcode.status = do_process_request(&msg);
|
msg.opcode.status = do_process_request(&msg);
|
||||||
|
|
||||||
@ -1276,25 +1291,25 @@ void dmeventd(void)
|
|||||||
/*
|
/*
|
||||||
* We exit when there are no more devices to watch.
|
* We exit when there are no more devices to watch.
|
||||||
* That is, when the last unregister happens.
|
* 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 {
|
do {
|
||||||
process_request(&fifos);
|
process_request(&fifos);
|
||||||
cleanup_unused_threads();
|
cleanup_unused_threads();
|
||||||
} while(!list_empty(&thread_registry));
|
} while(!list_empty(&thread_registry) || !list_empty(&thread_registry_unused));
|
||||||
|
|
||||||
/*
|
|
||||||
* 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();
|
|
||||||
}
|
|
||||||
|
|
||||||
exit_dm_lib();
|
exit_dm_lib();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user