1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-21 13:34:40 +03:00

libdm: Add dm_udev_wait_immediate.

dm_udev_wait() waits inside the library.
dm_udev_wait_immediate allows the caller to do other things if the
cookie isn't yet ready to be decremented.
This commit is contained in:
Alasdair G Kergon 2016-04-28 00:54:27 +01:00
parent a2d2a61339
commit 16019b518e
4 changed files with 58 additions and 2 deletions

View File

@ -1,5 +1,6 @@
Version 1.02.124 - Version 1.02.124 -
================================== ==================================
Add dm_udev_wait_immediate to libdevmapper for waiting outside the library.
Version 1.02.123 - 23rd April 2016 Version 1.02.123 - 23rd April 2016
================================== ==================================

View File

@ -0,0 +1 @@
dm_udev_wait_immediate

View File

@ -3218,6 +3218,15 @@ int dm_udev_create_cookie(uint32_t *cookie);
int dm_udev_complete(uint32_t cookie); int dm_udev_complete(uint32_t cookie);
int dm_udev_wait(uint32_t cookie); int dm_udev_wait(uint32_t cookie);
/*
* dm_dev_wait_immediate
* If *ready is 1 on return, the wait is complete.
* If *ready is 0 on return, the wait is incomplete and either
* this function or dm_udev_wait() must be called again.
* Returns 0 on error, when neither function should be called again.
*/
int dm_udev_wait_immediate(uint32_t cookie, int *ready);
#define DM_DEV_DIR_UMASK 0022 #define DM_DEV_DIR_UMASK 0022
#define DM_CONTROL_NODE_UMASK 0177 #define DM_CONTROL_NODE_UMASK 0177

View File

@ -2082,6 +2082,14 @@ int dm_udev_wait(uint32_t cookie)
return 1; return 1;
} }
int dm_udev_wait_immediate(uint32_t cookie, int *ready)
{
update_devs();
*ready = 1;
return 1;
}
#else /* UDEV_SYNC_SUPPORT */ #else /* UDEV_SYNC_SUPPORT */
static int _check_semaphore_is_supported(void) static int _check_semaphore_is_supported(void)
@ -2506,10 +2514,16 @@ int dm_udev_complete(uint32_t cookie)
return 1; return 1;
} }
static int _udev_wait(uint32_t cookie) /*
* If *nowait is set, return immediately leaving it set if the semaphore
* is not ready to be decremented to 0. *nowait is cleared if the wait
* succeeds.
*/
static int _udev_wait(uint32_t cookie, int *nowait)
{ {
int semid; int semid;
struct sembuf sb = {0, 0, 0}; struct sembuf sb = {0, 0, 0};
int val;
if (!cookie || !dm_udev_get_sync_support()) if (!cookie || !dm_udev_get_sync_support())
return 1; return 1;
@ -2517,6 +2531,21 @@ static int _udev_wait(uint32_t cookie)
if (!_get_cookie_sem(cookie, &semid)) if (!_get_cookie_sem(cookie, &semid))
return_0; return_0;
/* Return immediately if the semaphore value exceeds 1? */
if (*nowait) {
if ((val = semctl(semid, 0, GETVAL)) < 0) {
log_error("semid %d: sem_ctl GETVAL failed for "
"cookie 0x%" PRIx32 ": %s",
semid, cookie, strerror(errno));
return 0;
}
if (val > 1)
return 1;
*nowait = 0;
}
if (!_udev_notify_sem_dec(cookie, semid)) { if (!_udev_notify_sem_dec(cookie, semid)) {
log_error("Failed to set a proper state for notification " log_error("Failed to set a proper state for notification "
"semaphore identified by cookie value %" PRIu32 " (0x%x) " "semaphore identified by cookie value %" PRIu32 " (0x%x) "
@ -2548,11 +2577,27 @@ repeat_wait:
int dm_udev_wait(uint32_t cookie) int dm_udev_wait(uint32_t cookie)
{ {
int r = _udev_wait(cookie); int nowait = 0;
int r = _udev_wait(cookie, &nowait);
update_devs(); update_devs();
return r; return r;
} }
int dm_udev_wait_immediate(uint32_t cookie, int *ready)
{
int nowait = 1;
int r = _udev_wait(cookie, &nowait);
if (r && nowait) {
*ready = 0;
return 1;
}
update_devs();
*ready = 1;
return r;
}
#endif /* UDEV_SYNC_SUPPORT */ #endif /* UDEV_SYNC_SUPPORT */