<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META content="text/html; charset=us-ascii" http-equiv=Content-Type>
<META name=GENERATOR content="MSHTML 8.00.6001.23415"></HEAD>
<BODY 
style="WORD-WRAP: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space">
<DIV dir=ltr align=left><SPAN class=882214715-08112012><FONT color=#0000ff 
size=2 face=Arial>The windows (not CE) implementation wasn't threadsafe, so 
I've changed that code too.</FONT></SPAN></DIV>
<DIV dir=ltr align=left><SPAN class=882214715-08112012><FONT color=#0000ff 
size=2 face=Arial>Find attached the new GroupsockHelper.cpp. This solution is ok 
for us, so I won't spend any further time in this topic</FONT></SPAN></DIV><BR>
<DIV dir=ltr lang=en-us class=OutlookMessageHeader align=left>
<HR tabIndex=-1>
<FONT size=2 face=Tahoma><B>From:</B> live-devel-bounces@ns.live555.com 
[mailto:live-devel-bounces@ns.live555.com] <B>On Behalf Of </B>Ross 
Finlayson<BR><B>Sent:</B> Dienstag, 6. November 2012 16:00<BR><B>To:</B> LIVE555 
Streaming Media - development & use<BR><B>Subject:</B> Re: [Live-devel] 
Timestamp conversion in RTPSink.cpp<BR></FONT><BR></DIV>
<DIV></DIV>
<DIV>
<BLOCKQUOTE type="cite">
  <DIV 
  style="WORD-WRAP: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space">
  <DIV><SPAN style="FONT-FAMILY: Arial; FONT-SIZE: small">You can find alot 
  occurences of this problem in WinCE world. The problem is the 
  "GetSystemTime()" call, which should fill the SYSTEMTIME struct, but it does 
  not, at least not the milliseconds field (which is always 0). The solution I 
  used:</SPAN></DIV></DIV></BLOCKQUOTE></DIV>
<DIV>
<BLOCKQUOTE type="cite">
  <DIV 
  style="WORD-WRAP: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space">
  <DIV><SPAN class=719273517-05112012><FONT size=2 
  face=Arial></FONT></SPAN> </DIV>
  <DIV><SPAN class=719273517-05112012><FONT size=2 face="Courier New">int 
  gettimeofday(struct timeval* tp, int* /*tz*/) {<BR>#if 
  defined(_WIN32_WCE)<BR>  /* FILETIME of Jan 1 1970 00:00:00. */<BR>  
  static const unsigned __int64 epoch = 116444736000000000LL;<BR>  static 
  Boolean isFirstCall = True;<BR>  static LONGLONG unixStartTime = 
  0;<BR>  static DWORD firstTickCount=0;</FONT></SPAN></DIV>
  <DIV><FONT face="Courier New"></FONT> </DIV>
  <DIV><SPAN class=719273517-05112012><FONT size=2 face="Courier New">  if 
  (isFirstCall) {</FONT></SPAN></DIV>
  <DIV><FONT face="Courier New"></FONT> </DIV>
  <DIV><SPAN class=719273517-05112012><FONT size=2 
  face="Courier New">    FILETIME fileTime;</FONT></SPAN></DIV>
  <DIV><FONT face="Courier New"></FONT> </DIV>
  <DIV><SPAN class=719273517-05112012><FONT size=2 
  face="Courier New">    
  GetSystemTimeAsFileTime(&fileTime);</FONT></SPAN></DIV>
  <DIV><FONT face="Courier New"></FONT> </DIV>
  <DIV><SPAN class=719273517-05112012><FONT size=2 
  face="Courier New">    LARGE_INTEGER 
  date;<BR>    date.HighPart = 
  fileTime.dwHighDateTime;<BR>    date.LowPart = 
  fileTime.dwLowDateTime;</FONT></SPAN></DIV>
  <DIV><FONT face="Courier New"></FONT> </DIV>
  <DIV><SPAN class=719273517-05112012><FONT size=2 
  face="Courier New">    unixStartTime= (date.QuadPart - epoch) / 
  10000000L;</FONT></SPAN></DIV>
  <DIV><FONT face="Courier New"></FONT> </DIV>
  <DIV><SPAN class=719273517-05112012><FONT size=2 
  face="Courier New">    firstTickCount = 
  GetTickCount();</FONT></SPAN></DIV>
  <DIV><FONT face="Courier New"></FONT> </DIV>
  <DIV><SPAN class=719273517-05112012><FONT size=2 
  face="Courier New">    
  tp->tv_sec=(long)unixStartTime;<BR>    tp->tv_usec= 
  0L;</FONT></SPAN></DIV>
  <DIV><FONT face="Courier New"></FONT> </DIV>
  <DIV><SPAN class=719273517-05112012><FONT size=2 
  face="Courier New">    isFirstCall = False; // for next 
  time</FONT></SPAN></DIV>
  <DIV><FONT face="Courier New"></FONT> </DIV>
  <DIV><SPAN class=719273517-05112012><FONT size=2 face="Courier New">  } 
  else {<BR>    // add elapsed seconds<BR>    
  tp->tv_sec= (long)unixStartTime + 
  (GetTickCount()-firstTickCount)/1000;<BR>    
  tp->tv_usec=(GetTickCount()-firstTickCount)%1000 * 
  1000;<BR>}</FONT></SPAN></DIV>
  <DIV><FONT face="Courier New"></FONT> </DIV>
  <DIV><SPAN class=719273517-05112012><FONT size=2 
  face="Courier New">#else</FONT></SPAN></DIV></DIV></BLOCKQUOTE>
<DIV><BR></DIV></DIV>Correction: On further thought, I don't want to make this 
change 'as is'.  The problem is that it's possible for the "gettimeofday()" 
function to be called concurrently from multiple threads.  (This is legal 
for LIVE555-based systems that use different "UsageEnvironment" and 
"TaskScheduler" objects for each thread.)  So, the implementation needs to 
be 'thread safe'.  If the "if" branch of the "if (isFirstCall)" statement 
gets executed concurrently by more than one thread, then "unixStartTime" and/or 
"firstTickCount" might get set to bad values.
<DIV><BR></DIV>
<DIV>So, please rewrite your implementation to ensure that the "if" branch of 
the code (i.e., the part of the code that sets static variables) is executed 
only once, even if the code is called by multiple threads.  (Because this 
code is for WinCE only, it's OK to use some WinCE-specific locking mechanism, if 
necessary.)</DIV>
<DIV><BR></DIV>
<DIV>(However, I'll make the change to the timestamp conversion code in the next 
release of the software.)<BR><BR>
<DIV apple-content-edited="true"><SPAN 
style="BORDER-SPACING: 0px; BORDER-COLLAPSE: separate" 
class=Apple-style-span>Ross Finlayson<BR>Live Networks, Inc.<BR><A 
href="http://www.live555.com/">http://www.live555.com/</A></SPAN> 
</DIV><BR></DIV></BODY></HTML>