git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH 1/2] Support for setitimer() on platforms lacking it

From
Junio C Hamano <gitster@pobox.com>
Date
Aug 28, 2012, 20:15 UTC
Message-ID
<7vr4qqzsbe.fsf@alter.siamese.dyndns.org>
In-Reply-To
<003301cd81e4$cd68daa0$683a8fe0$@schmitz-digital.de>
"Joachim Schmitz" <jojo@schmitz-digital.de> writes:
Show 36 quoted lines
> Implementation includes getitimer(), but for now it is static.
> Supports ITIMER_REAL only.
>
> Signed-off-by: Joachim Schmitz <jojo@schmitz-digital.de>
> ---
> May need a header file for ITIMER_*, struct itimerval and the prototypes,
> But for now, and the HP NonStop platform this isn't needed, here
> <sys/time> has ITIMER_* and struct timeval, and the prototypes can 
> vo into git-compat-util.h for now (Patch 2/2) 
>
>  compat/itimer.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 50 insertions(+)
>  create mode 100644 compat/itimer.c
>
> diff --git a/compat/itimer.c b/compat/itimer.c
> new file mode 100644
> index 0000000..713f1ff
> --- /dev/null
> +++ b/compat/itimer.c
> @@ -0,0 +1,50 @@
> +#include "../git-compat-util.h"
> +
> +static int git_getitimer(int which, struct itimerval *value)
> +{
> +	int ret = 0;
> +
> +	switch (which) {
> +		case ITIMER_REAL:
> +			value->it_value.tv_usec = 0;
> +			value->it_value.tv_sec = alarm(0);
> +			ret = 0; /* if alarm() fails, we get a SIGLIMIT */
> +			break;
> +		case ITIMER_VIRTUAL: /* FALLTHRU */
> +		case ITIMER_PROF: errno = ENOTSUP; ret = -1; break;
> +		default: errno = EINVAL; ret = -1;
> +	}

Just a style thing, but we align case arms and switch statements, like this:

	switch (which) {
        case ...:
        	stmt;
                break;
	default:
        	stmt;
                break;
	}
	
Because alarm() runs in integral seconds granularity, this could
return 0.0 sec (i.e. "do not re-trigger this alarm any more") in
ovalue after setting alarm(1) (via git_setitimer()) and calling this
function (via git_setitimer() again) before the timer expires, no?
Is it a desired behaviour?

What I am most worried about is that callers _might_ take this emulation too seriously, grab the remainder from getitimer(), and drives a future call to getitimer() with the returned value, and accidentally cause the "recurring" nature of the request to be disabled.

I see no existing code calls setitimer() with non-NULL ovalue, and I do not think we would add a new caller that would do so in any time soon, so it may not be a bad idea to drop support of returning the remaining timer altogether from this emulation layer (just like giving anything other than ITIMER_REAL gives us ENOTSUP). That would sidestep the whole "we cannot answer how many milliseconds are still remaining on the timer when using emulation based on alarm()".

Show 22 quoted lines
> +int git_setitimer(int which, const struct itimerval *value,
> +				struct itimerval *ovalue)
> +{
> +	int ret = 0;
> +
> +	if (!value
> +		|| value->it_value.tv_usec < 0
> +		|| value->it_value.tv_usec > 1000000
> +		|| value->it_value.tv_sec < 0) {
> +		errno = EINVAL;
> +		return -1;
> +	}
> +
> +	else if (ovalue)
> +		if (!git_getitimer(which, ovalue))
> +			return -1; /* errno set in git_getitimer() */
> +
> +	else
> +	switch (which) {
> +		case ITIMER_REAL:
> +			alarm(value->it_value.tv_sec +
> +				(value->it_value.tv_usec > 0) ? 1 : 0);

Why is this capped to 1 second? Is this because no existing code uses the timer for anything other than 1 second or shorter? If that is the case, that needs at least some documenting (or a possibly support for longer expiration, if it is not too cumbersome to add).

> +			ret = 0; /* if alarm() fails, we get a SIGLIMIT */
> +			break;
> +		case ITIMER_VIRTUAL: /* FALLTHRU */
> +		case ITIMER_PROF: errno = ENOTSUP; ret = -1; break;

Please don't add a misleading "fallthru" label here. We do not say "fallthru" when "two case arms do _exactly_ the same thing". Only when the one arm does some pre-action before the common action, i.e.

	switch (which) {
        case one:
        	do some thing specific to one;
                /* fallthru */
	case two:
		do some thing common between one and two;
		break;
	}                
        
we label it "fallthru" to make it clear to the readers that it is
not "missing a break" but is deliberate.
Show 5 quoted lines
> +		default: errno = EINVAL; ret = -1;
> +	}
> +
> +	return ret;
> +}
Thanks.
Previous: Joachim SchmitzNext: Joachim Schmitz
Message 2 of 20 in “Support for setitimer() on platforms lacking it”
  1. 1/2 Support for setitimer() on platforms lacking itJoachim Schmitz, Aug 24, 2012
  2. Junio C HamanoAug 28, 2012
  3. Joachim SchmitzAug 30, 2012
  4. Junio C HamanoAug 30, 2012
  5. Joachim SchmitzAug 30, 2012
  6. Joachim SchmitzSep 1, 2012
  7. Junio C HamanoSep 2, 2012
  8. Joachim SchmitzSep 3, 2012
  9. Johannes SixtSep 3, 2012
  10. Junio C HamanoSep 3, 2012
  11. Junio C HamanoSep 3, 2012
  12. Joachim SchmitzSep 3, 2012
  13. Junio C HamanoSep 4, 2012
  14. Joachim SchmitzSep 4, 2012
  15. Junio C HamanoSep 4, 2012
  16. Junio C HamanoSep 4, 2012
  17. Joachim SchmitzSep 4, 2012
  18. Junio C HamanoSep 4, 2012
  19. Joachim SchmitzSep 5, 2012
  20. Johannes SixtSep 4, 2012

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.