PDA

View Full Version : tv_usec range for select function?




hajiman
May 20, 2011, 07:56 PM
I am doing serial port programming using XCODE 4. My read() calls are set to blocking mode so I use the select() function to block up to a certain time limit before I call read(). In order to get a little bit finer resolution than seconds, I use the tv_usec field to specify how long select should block before returning. The problem I am having is when I specify a microsecond value > 999,999 select immediately returns reporting error == 22 (EINVAL = Invalid argument), essentially saying the time out value is incorrect. I don't see any documentation anywhere stating the microsecond value has to be smaller than 1 second(1,000,000us). The variable is an int so it should be able to hold quite a large value. Is this a bug in select() or some undocumented behavior or am I missing something obvious(which happens quite often)?

....This works
tv.tv_sec = 0;
tv.tv_usec = 999999;

wait_result = select(file_descriptor + 1, &read_flags, NULL, NULL, &tv);

....This doesn't
tv.tv_sec = 0;
tv.tv_usec = 1000000;

wait_result = select(file_descriptor + 1, &read_flags, NULL, NULL, &tv);



Cromulent
May 20, 2011, 08:29 PM
I am doing serial port programming using XCODE 4. My read() calls are set to blocking mode so I use the select() function to block up to a certain time limit before I call read(). In order to get a little bit finer resolution than seconds, I use the tv_usec field to specify how long select should block before returning. The problem I am having is when I specify a microsecond value > 999,999 select immediately returns reporting error == 22 (EINVAL = Invalid argument), essentially saying the time out value is incorrect. I don't see any documentation anywhere stating the microsecond value has to be smaller than 1 second(1,000,000us). The variable is an int so it should be able to hold quite a large value. Is this a bug in select() or some undocumented behavior or am I missing something obvious(which happens quite often)?

....This works
tv.tv_sec = 0;
tv.tv_usec = 999999;

wait_result = select(file_descriptor + 1, &read_flags, NULL, NULL, &tv);

....This doesn't
tv.tv_sec = 0;
tv.tv_usec = 1000000;

wait_result = select(file_descriptor + 1, &read_flags, NULL, NULL, &tv);

Err why not try:

tv.tv_sec = 1;
tv.tv_usec = 0;

?

hajiman
May 20, 2011, 09:15 PM
Err why not try:

tv.tv_sec = 1;
tv.tv_usec = 0;

?

Sure, that is how I ended up getting around this problem. I pass my function a value in milliseconds and do the following conversion:
tv.tv_sec = *ms_timeout / 1000;
tv.tv_usec = 1000 * (*ms_timeout % 1000);

My question is more geared towards whether others think this might be a bug in the select() function.

mfram
May 21, 2011, 12:13 AM
My question is more geared towards whether others think this might be a bug in the select() function.

Considering the fields are referred to as seconds and "micro-seconds", I would make the assumption the tv_usec field is used to specify granularity of less than a second, not more than a second. In other words, not a bug.

Cromulent
May 21, 2011, 05:50 AM
Considering the fields are referred to as seconds and "micro-seconds", I would make the assumption the tv_usec field is used to specify granularity of less than a second, not more than a second. In other words, not a bug.


My question is more geared towards whether others think this might be a bug in the select() function.

As mfram posted above it seems pretty obvious from the documentation that the usec field is meant for values less than a second. So I would agree with him and say it is not a bug.

willieva
May 21, 2011, 05:21 PM
From the man page for select:
[EINVAL] The specified time limit is invalid. One of its components is negative or too large.