#262 Data requests in pull mode dont timeout

closed-fixed
Brian Gerkey
player (137)
5
2009-01-06
2009-01-03
Toby Collett
No

Dear all,

I have been facing a problem for quite a while, and I didn't find any
way to solve it.
I am using the player 2.1.1 release which features signals and threads
inherited from the boost library, which is a library that I am used to.
In my application, I connect to a (stage) robot, set the retry limit to
infinity, I set up signals to go to read the different proxies and then
I start the robot thread (PlayerClient::StartThread).
Then I stop the stage simulation and it tries to reconnect. When I
launch stage again, on my client console, a player comment is written
saying that I successfully reconnected to the robot, but then I never
get anything on my signals callbacks.
I first thought that it is a signal program, and that the signals are
not reconnected upon reconnection of the robot, but when I inspect the
backtrace of player, I see that it is blocked into the Read method of
the PlayerClient...

I would like to know how this is supposed to work; if in the
implementation the signals are still connected after a deconnection; if
other people are facing this problem...

Thanks,

Elvina

------------------------------------------------------------------------------
SF.Net email is Sponsored by MIX09, March 18-20, 2009 in Las Vegas, Nevada.
The future of the web can't happen without you. Join us at MIX09 to help
pave the way to the Next Web now. Learn more and register at
http://ad.doubleclick.net/clk;208669438;13503038;i?http://2009.visitmix.com/
_______________________________________________
Playerstage-developers mailing list
Playerstage-developers@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/playerstage-developers
Reply

Forward

Peter Nordin
to playerstage-de.

show details 15/12/2008

Reply

Hello

I recently had similar problems. I am trying to communicate over wlan
between to computers but when the range is to large, or if the wlan
fails the player servers will crash. (The player read functions throws
an exception). Anyway I tried using the threaded read with boost but was
unable to make it work. Instead I am using try catch on my read in order
to capture the failed read and handle the situation in some way. Anyway
to make a long boring story a bit shorter, I found something strange in
client.c that might be relevant for your problem. The playerclient uses
pull-mode as default apparently. And in the code after the
“pull-request” has been sent there is a while loop that peak onto the
socket to see if data has arrived. If no data is found the peek times
out after 10ms and returns 0. If 0 is returned the while loop restarts.
If not, a time variable is decreased and data is read. The problem is
that when no data is received the peek will always return 0 and the loop
will never end. For me this occurs if the two computers are to far away
from each other so that the pull request does not reach the other computer.

The problem is near row 770 in client.c. Bellow is the original code and
later my “fixed version”
To work around this I added a counter that counts to 100 (hard coded) =
1 second timeout and then returns -1 if no data is received. This is a
crude “fix” but I was in a hurry. I don't know if this will help at all
but maybe it could be useful. I really should report this in the bug
tracker, I might do that later today if I have time. If anyone has any
opinions about this please let me know. Maybe I have completely
misunderstood something.

/Peter Nordin

Original:

// Read packets until we get a reply. Data packets get queued up
// for later processing.
while(t >= 0)
{
gettimeofday(&last,NULL);

// Peek at the socket
if((peek = playerc_client_internal_peek(client,10)) < 0)
return -1;
else if(peek == 0)
continue;
// There's data on the socket, so read a packet (blocking).
if(playerc_client_readpacket(client, &rep_header, client->data) < 0)

“Fixed”: (Note the + and – signs for new and removed rows of code)

// Read packets until we get a reply. Data packets get queued up
// for later processing.
+ peek0ctr = 0;
while(t >= 0)
{
gettimeofday(&last,NULL);

// Peek at the socket
if((peek = playerc_client_internal_peek(client,10)) < 0)
return -1;
else if(peek == 0)
- continue;
+ {
+ peek0ctr = peek0ctr+1;
+ if (peek0ctr >= 100)
+ {
+ return -1;
+ }
+ else
+ continue;
+ }
+ peek0ctr = 0;

// There's data on the socket, so read a packet (blocking).
if(playerc_client_readpacket(client, &rep_header, client->data) < 0)
- Show quoted text -

Elvina Motard wrote:
> Dear all,
>
> I have been facing a problem for quite a while, and I didn't find any
> way to solve it.
> I am using the player 2.1.1 release which features signals and threads
> inherited from the boost library, which is a library that I am used to.
> In my application, I connect to a (stage) robot, set the retry limit to
> infinity, I set up signals to go to read the different proxies and then
> I start the robot thread (PlayerClient::StartThread).
> Then I stop the stage simulation and it tries to reconnect. When I
> launch stage again, on my client console, a player comment is written
> saying that I successfully reconnected to the robot, but then I never
> get anything on my signals callbacks.
> I first thought that it is a signal program, and that the signals are
> not reconnected upon reconnection of the robot, but when I inspect the
> backtrace of player, I see that it is blocked into the Read method of
> the PlayerClient...
>
> I would like to know how this is supposed to work; if in the
> implementation the signals are still connected after a deconnection; if
> other people are facing this problem...
>
> Thanks,
>
> Elvina
>
>
> ------------------------------------------------------------------------------
> SF.Net email is Sponsored by MIX09, March 18-20, 2009 in Las Vegas, Nevada.
> The future of the web can't happen without you. Join us at MIX09 to help
> pave the way to the Next Web now. Learn more and register at
> http://ad.doubleclick.net/clk;208669438;13503038;i?http://2009.visitmix.com/
> _______________________________________________
> Playerstage-developers mailing list
> Playerstage-developers@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/playerstage-developers
>

Discussion

  • Toby Collett
    Toby Collett
    2009-01-05

    Does the following patch correct the problem? The if structure around peek was short circuiting the timeout logic already in the request method...

    Index: client_libs/libplayerc/client.c

    --- client_libs/libplayerc/client.c (revision 7226)
    +++ client_libs/libplayerc/client.c (working copy)
    @@ -765,15 +765,19 @@
    return playerc_client_writepacket(client, &header, cmd);
    }

    +inline double tdiff (const struct timeval t1, const struct timeval t2)
    +{
    + return (double)(t2.tv_sec - t1.tv_sec) + (double)(t2.tv_usec - t1.tv_usec)/1e6;
    +}
    +
    // Issue request and await reply (blocking).
    int playerc_client_request(playerc_client_t *client,
    playerc_device_t *deviceinfo,
    uint8_t subtype,
    const void *req_data, void **rep_data)
    {
    - double t;
    int peek;
    - struct timeval last;
    + struct timeval start;
    struct timeval curr;
    player_msghdr_t req_header, rep_header;
    memset(&req_header, 0, sizeof(req_header));
    @@ -795,14 +799,11 @@
    if (playerc_client_writepacket(client, &req_header, req_data) < 0)
    return -1;

    - t = client->request_timeout;
    -
    // Read packets until we get a reply. Data packets get queued up
    // for later processing.
    - while(t >= 0)
    + gettimeofday(&start,NULL);
    + for(curr = start; tdiff(start,curr)< client->request_timeout; gettimeofday(&curr,NULL))
    {
    - gettimeofday(&last,NULL);
    -
    // Peek at the socket
    if((peek = playerc_client_internal_peek(client,10)) < 0)
    return -1;
    @@ -812,9 +813,6 @@
    // There's data on the socket, so read a packet (blocking).
    if(playerc_client_readpacket(client, &rep_header, client->data) < 0)
    return -1;
    - gettimeofday(&curr,NULL);
    - t -= ((curr.tv_sec + curr.tv_usec/1e6) -
    - (last.tv_sec + last.tv_usec/1e6));

    if (rep_header.type == PLAYER_MSGTYPE_DATA || rep_header.type == PLAYER_MSGTYPE_SYNCH)
    {

     
  • Toby Collett
    Toby Collett
    2009-01-06

    • status: open --> closed-fixed
     
  • Toby Collett
    Toby Collett
    2009-01-06

    This issue should be fixed in trunk and 2.1