Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 23 additions & 11 deletions ext/standard/uniqid.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,20 +53,32 @@ PHP_FUNCTION(uniqid)
Z_PARAM_BOOL(more_entropy)
ZEND_PARSE_PARAMETERS_END();

/* This implementation needs current microsecond to change,
* hence we poll time until it does. This is much faster than
* calling usleep(1) which may cause the kernel to schedule
* another process, causing a pause of around 10ms.
/* This implementation needs current microsecond to change.
* We will manually move the time forward if needed. This is
* more stable as polling or sleeping as it will not be
* effected by time changes (like ntp) and this is much faster
* than calling usleep(1) which may cause the kernel to
* schedule another process, causing a pause of around 10ms.
*/
do {
(void)gettimeofday((struct timeval *) &tv, (struct timezone *) NULL);
} while (tv.tv_sec == prev_tv.tv_sec && tv.tv_usec == prev_tv.tv_usec);
(void)gettimeofday((struct timeval *) &tv, (struct timezone *) NULL);
if (UNEXPECTED((tv.tv_sec == prev_tv.tv_sec && tv.tv_usec <= prev_tv.tv_usec)
|| tv.tv_sec < prev_tv.tv_sec
)) {
prev_tv.tv_usec += 1;
if (UNEXPECTED(prev_tv.tv_usec > 999999)) {
prev_tv.tv_sec += prev_tv.tv_usec / 1000000;
prev_tv.tv_usec = prev_tv.tv_usec % 1000000;
}

prev_tv.tv_sec = tv.tv_sec;
prev_tv.tv_usec = tv.tv_usec;
sec = (int) prev_tv.tv_sec;
usec = (int) prev_tv.tv_usec;
} else {
prev_tv.tv_sec = tv.tv_sec;
prev_tv.tv_usec = tv.tv_usec;

sec = (int) tv.tv_sec;
usec = (int) (tv.tv_usec % 0x100000);
sec = (int) tv.tv_sec;
usec = (int) (tv.tv_usec % 0x100000);
}

/* The max value usec can have is 0xF423F, so we use only five hex
* digits for usecs.
Expand Down