<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <meta content="text/html; charset=ISO-8859-15"
      http-equiv="Content-Type">
    <title></title>
  </head>
  <body text="#000000" bgcolor="#ffffff">
    Il 06/04/2011 18:49, Cristiano Belloni ha scritto:
    <blockquote cite="mid:4D9C997C.4060802@imavis.com" type="cite">
      <meta content="text/html; charset=ISO-8859-15"
        http-equiv="Content-Type">
      Il 06/04/2011 12:04, Cristiano Belloni ha scritto:
      <blockquote cite="mid:4D9C3AA2.40404@imavis.com" type="cite">
        <meta http-equiv="content-type" content="text/html;
          charset=ISO-8859-15">
        Hi to all,<br>
        I wrote a custom shared memory source. it inherits from
        FramedSource.<br>
        The shared memory is synchronized via Linux semaphores (simple
        producer-consumer algorithm), but since I didn't want to
        subclass TaskScheduler, I still use a "dummy" file
        descriptor-based communication with live555. In pseudocode:<br>
        <br>
        <br>
        ~~~Client (without live555):<br>
        <br>
        wait on semaphore_empty (blocking)<br>
        copy frame in shared memory<br>
        write one byte in a dedicated FIFO (this should wake up live555'
        TaskScheduler select())<br>
        post on semaphore_fill<br>
        <br>
        ~~~Server (with live555, in
        SharedMemSource::incomingPacketHandler1())<br>
        [turnOnBackgroundReadHandling is called in doGetNextFrame]<br>
        <br>
        wait on semaphore_fill (blocking)<br>
        read one byte from the dedicated FIFO (to flush the FIFO buffer)<br>
        copy frame from shared memory<br>
        post on semaphore_empty<br>
        <br>
        This works. Altought the blocking wait on semaphore_fill might
        make you wonder, the client wakes up my source with the write()
        in the dedicated FIFO and immediately posts on semaphore_fill,
        so the server almost never waits, and if it does, it doesn't
        block for a really small time.<br>
        <br>
        The problem is that, after a while (1 or 2 hours usually), the
        client does its cycle and the server never wakes up. It
        *doesn't* get stuck on the wait, I checked: it simply never
        wakes up, as if the client write() was lost (but it *always*
        succeed on the client side) or the select() didn't wake up even
        if the write succeeded.<br>
        <br>
        I would like to emphasize this: the server *never* gets stuck
        forever on its wait. When it gets stuck, the client is one frame
        ahead of the server, incomingPacketHandler1() simply is never
        called anymore and the wait is not even reached.<br>
        <br>
        At this point, I have two questions:<br>
        <br>
        1) In your knowledge, can the select() not wake up even if a
        write() on the other side succeeded? If it can, how is it
        possible? Note that the system is an embedded ARM processor, and
        it could get quite busy while acquiring and streaming video.<br>
        <br>
        2) First thing I do in SharedMemSource::incomingPacketHandler1()
        is to check for isCurrentlyAwaitingData(). If it's false, I
        simply return before doing all the cycle, and this happens quite
        often. What's the meaning of isCurrentlyAwaitingData()? I mean,
        if the select() in TaskScheduler returned, some data must be
        present on the file/fifo/socket. How is it possible that the
        select() did return but still there's no data available? I'm
        getting really confused on this.<br>
        <br>
        Thanks and regards,<br>
        Cristiano Belloni.<br>
        <br>
        <br>
        <div class="moz-signature">-- <br>
          <title></title>
          Belloni Cristiano<br>
          Imavis Srl.<br>
          <a moz-do-not-send="true" href="http://www.imavis.com">www.imavis.com</a><br>
          <a moz-do-not-send="true" href="mailto://belloni@imavis.com">belloni@imavis.com</a><br>
        </div>
        <pre wrap=""><fieldset class="mimeAttachmentHeader"></fieldset>
_______________________________________________
live-devel mailing list
<a moz-do-not-send="true" class="moz-txt-link-abbreviated" href="mailto:live-devel@lists.live555.com">live-devel@lists.live555.com</a>
<a moz-do-not-send="true" class="moz-txt-link-freetext" href="http://lists.live555.com/mailman/listinfo/live-devel">http://lists.live555.com/mailman/listinfo/live-devel</a>
</pre>
      </blockquote>
      <br>
      Update: I put some logs in BasicTaskScheduler to see what happens.<br>
      <br>
      one before the select():<br>
      <br>
      printf ("[SYNCHROBUG] About to do the select, timeout %d.%d\n",
      tv_timeToDelay.tv_sec, tv_timeToDelay.tv_usec);<br>
          int selectResult = select(fMaxNumSockets, &readSet,
      &writeSet, &exceptionSet, &tv_timeToDelay);<br>
          if (selectResult < 0) {<br>
      [...]<br>
      <br>
      two after the select(), (one catches an EINTR or EAGAIN  error
      value should they happen):<br>
      <br>
      #else<br>
          if (errno != EINTR && errno != EAGAIN) {<br>
      #endif<br>
              // Unexpected error - treat this as fatal:<br>
      #if !defined(_WIN32_WCE)<br>
              perror("BasicTaskScheduler::SingleStep(): select()
      fails");<br>
      #endif<br>
              internalError();<br>
            }<br>
        }<br>
          if (errno == EINTR || errno == EAGAIN) {<br>
             perror ("[SYNCHROBUG] error is");<br>
          }<br>
      <br>
        printf ("[SYNCHROBUG] Select done, getting sockets\n");<br>
      [...]<br>
      <br>
      two after the first and second pass of readable socket check:<br>
      <br>
       int resultConditionSet = 0;<br>
          if (FD_ISSET(sock, &readSet) && FD_ISSET(sock,
      &fReadSet)/*sanity check*/) {<br>
             printf ("[SYNCHROBUG] Socket %d found readable on first
      pass\n", sock);<br>
             resultConditionSet |= SOCKET_READABLE;<br>
          }<br>
      <br>
          [...]<br>
      <br>
            if (FD_ISSET(sock, &readSet) && FD_ISSET(sock,
      &fReadSet)/*sanity check*/) {<br>
               printf ("[SYNCHROBUG] Socket %d found readable on second
      pass\n", sock);<br>
               resultConditionSet |= SOCKET_READABLE;<br>
            }<br>
      <br>
      And one to check if we found some readable/writable/excepting
      socket at all:<br>
      <br>
      <br>
      if (handler == NULL) {<br>
             fLastHandledSocketNum = -1;//because we didn't call a
      handler<br>
             printf ("[SYNCHROBUG] No socket found at all\n");<br>
          }<br>
      <br>
      <br>
      at first everything is ok:<br>
      <br>
      [SYNCHROBUG] About to do the select, timeout 0.0<br>
      [SYNCHROBUG] Select done, getting sockets<br>
      [SYNCHROBUG] No socket found at all<br>
      [SYNCHROBUG] About to do the select, timeout 0.0<br>
      [SYNCHROBUG] Select done, getting sockets<br>
      [SYNCHROBUG] About to do the select, timeout 0.0<br>
      [SYNCHROBUG] Select done, getting sockets<br>
      [SYNCHROBUG] Socket 5 found readable on first pass<br>
      [SYNCHROBUG] About to do the select, timeout 0.0<br>
      [SYNCHROBUG] Select done, getting sockets<br>
      [SYNCHROBUG] Socket 5 found readable on second pass<br>
      [SYNCHROBUG] About to do the select, timeout 0.0<br>
      [SYNCHROBUG] Select done, getting sockets<br>
      [SYNCHROBUG] Socket 5 found readable on second pass<br>
      [SYNCHROBUG] About to do the select, timeout 0.0<br>
      [SYNCHROBUG] Select done, getting sockets<br>
      [SYNCHROBUG] Socket 5 found readable on second pass<br>
      [SYNCHROBUG] About to do the select, timeout 0.0<br>
      [SYNCHROBUG] Select done, getting sockets<br>
      [SYNCHROBUG] Socket 5 found readable on second pass<br>
      [SYNCHROBUG] About to do the select, timeout 0.0<br>
      [SYNCHROBUG] Select done, getting sockets<br>
      [SYNCHROBUG] Socket 5 found readable on second pass<br>
      <br>
      (socket 5 must be the FIFO, I guess)<br>
      <br>
      <br>
      But then, select keeps randomly return errno=11, aka EAGAIN or
      "Resource temporarily unavailable":<br>
      <br>
      [SYNCHROBUG] Select done, getting sockets<br>
      [SYNCHROBUG] Socket 5 found readable on second pass<br>
      [SYNCHROBUG] About to do the select, timeout 1.480311<br>
      [SYNCHROBUG] error is: Resource temporarily unavailable<br>
      [SYNCHROBUG] Select done, getting sockets<br>
      [SYNCHROBUG] Socket 6 found readable on first pass<br>
      [SYNCHROBUG] About to do the select, timeout 1.479309<br>
      [SYNCHROBUG] error is: Resource temporarily unavailable<br>
      [SYNCHROBUG] Select done, getting sockets<br>
      [SYNCHROBUG] Socket 5 found readable on second pass<br>
      [SYNCHROBUG] About to do the select, timeout 1.478362<br>
      [SYNCHROBUG] error is: Resource temporarily unavailable<br>
      [SYNCHROBUG] Select done, getting sockets<br>
      [SYNCHROBUG] Socket 6 found readable on first pass<br>
      [SYNCHROBUG] About to do the select, timeout 1.477358<br>
      [SYNCHROBUG] error is: Resource temporarily unavailable<br>
      [SYNCHROBUG] Select done, getting sockets<br>
      [SYNCHROBUG] Socket 5 found readable on second pass<br>
      [SYNCHROBUG] About to do the select, timeout 1.476431<br>
      [SYNCHROBUG] error is: Resource temporarily unavailable<br>
      [SYNCHROBUG] Select done, getting sockets<br>
      [SYNCHROBUG] Socket 6 found readable on first pass<br>
      <br>
      Now, I don't even know the reason why a select() could return
      EAGAIN (a lot of people say it souldn't at all, and even my "man 3
      select" agrees: <a moz-do-not-send="true"
        class="moz-txt-link-freetext"
href="http://stackoverflow.com/questions/4193043/select-on-a-pipe-in-blocking-mode-returns-eagain">http://stackoverflow.com/questions/4193043/select-on-a-pipe-in-blocking-mode-returns-eagain</a>
      ), but I see this case is handled in your code and ignored, just
      like the EINTR case:<br>
      <br>
          if (errno != EINTR && errno != EAGAIN) {<br>
      #endif<br>
              // Unexpected error - treat this as fatal:<br>
      #if !defined(_WIN32_WCE)<br>
              perror("BasicTaskScheduler::SingleStep(): select()
      fails");<br>
      #endif<br>
              internalError();<br>
            }<br>
      <br>
      [if errno is EINTR or EAGAIN, then the scheduler goes on
      inspecting the select()'s returned sets].<br>
      <br>
      Could that be the origin of my problems?<br>
      <br>
      As obviously you can't try my executables on my hardware, please
      tell me what else could I log. BTW the rtsp/rtp client in this
      picture is openRTSP. Here's an ascii schema :)<br>
      <br>
      client program generating frames ----FIFO---> rtsp server based
      on live555 ----RTSP/RTP/TCP----> openRTSP<br>
      <br>
      Thank you and best regards,<br>
      <br>
      Cristiano Belloni.<br>
      <br>
      <br>
      <div class="moz-signature">-- <br>
        <title></title>
        Belloni Cristiano<br>
        Imavis Srl.<br>
        <a moz-do-not-send="true" href="http://www.imavis.com">www.imavis.com</a><br>
        <a moz-do-not-send="true" href="mailto://belloni@imavis.com">belloni@imavis.com</a><br>
      </div>
      <pre wrap="">
<fieldset class="mimeAttachmentHeader"></fieldset>
_______________________________________________
live-devel mailing list
<a class="moz-txt-link-abbreviated" href="mailto:live-devel@lists.live555.com">live-devel@lists.live555.com</a>
<a class="moz-txt-link-freetext" href="http://lists.live555.com/mailman/listinfo/live-devel">http://lists.live555.com/mailman/listinfo/live-devel</a>
</pre>
    </blockquote>
    Ok, it was a problem related to the timestamp calculations, which
    you fixed in the last version. Disregard this.<br>
    <br>
    Cristiano.<br>
    <br>
    <div class="moz-signature">-- <br>
      <title></title>
      Belloni Cristiano<br>
      Imavis Srl.<br>
      <a href="http://www.imavis.com">www.imavis.com</a><br>
      <a href="mailto://belloni@imavis.com">belloni@imavis.com</a><br>
    </div>
  </body>
</html>