<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.deltaworlds.com/index.php?action=history&amp;feed=atom&amp;title=Aw_wait</id>
	<title>Aw wait - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.deltaworlds.com/index.php?action=history&amp;feed=atom&amp;title=Aw_wait"/>
	<link rel="alternate" type="text/html" href="https://wiki.deltaworlds.com/index.php?title=Aw_wait&amp;action=history"/>
	<updated>2026-04-17T00:31:15Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.39.3</generator>
	<entry>
		<id>https://wiki.deltaworlds.com/index.php?title=Aw_wait&amp;diff=201&amp;oldid=prev</id>
		<title>Xan: Created page with &quot;{{SDK added in|version=2.1|sdk=13|world=|universe=|browser=}}  __NOTOC__   int aw_wait (int &lt;var&gt;milliseconds&lt;/var&gt;)  ==Description== Processes all queued packets and waits the specified time for more to arrive, calling callback and event handlers.  ==Callback== None  ==Notes== Placing calls to this method from callback or event handlers should be avoided. The reason for this being that it will in turn call such handlers. Which would cause aw_wait to indirectly call itse...&quot;</title>
		<link rel="alternate" type="text/html" href="https://wiki.deltaworlds.com/index.php?title=Aw_wait&amp;diff=201&amp;oldid=prev"/>
		<updated>2025-04-07T19:27:37Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;{{SDK added in|version=2.1|sdk=13|world=|universe=|browser=}}  __NOTOC__   int aw_wait (int &amp;lt;var&amp;gt;milliseconds&amp;lt;/var&amp;gt;)  ==Description== Processes all queued packets and waits the specified time for more to arrive, calling callback and event handlers.  ==Callback== None  ==Notes== Placing calls to this method from callback or event handlers should be avoided. The reason for this being that it will in turn call such handlers. Which would cause aw_wait to indirectly call itse...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{{SDK added in|version=2.1|sdk=13|world=|universe=|browser=}}&lt;br /&gt;
&lt;br /&gt;
__NOTOC__&lt;br /&gt;
&lt;br /&gt;
 int aw_wait (int &amp;lt;var&amp;gt;milliseconds&amp;lt;/var&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
==Description==&lt;br /&gt;
Processes all queued packets and waits the specified time for more to arrive, calling callback and event handlers.&lt;br /&gt;
&lt;br /&gt;
==Callback==&lt;br /&gt;
None&lt;br /&gt;
&lt;br /&gt;
==Notes==&lt;br /&gt;
Placing calls to this method from callback or event handlers should be avoided. The reason for this being that it will in turn call such handlers. Which would cause aw_wait to indirectly call itself (e.g. aw_wait calls handler, handler calls aw_wait, repeat).&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;For version 4.1 and later:&amp;#039;&amp;#039;&amp;#039; This method will deallocate [[SDK_Multiple_Instances|instances]] that have been flagged as destroyed by [[aw_destroy]]. This is done before each iteration of processing packets for all the instances. If an application places a call to [[aw_destroy]] followed by aw_wait within a callback or event handler then it could cause the SDK to dereference a pointer to freed memory.&lt;br /&gt;
&lt;br /&gt;
===Blocking calls===&lt;br /&gt;
It helps to think of blocking calls to SDK methods as placing an implicit call to aw_wait. That is, calls that have a callback but none has been registered. A blocking call will process all packets until it receives the result. This includes packets bound for other instances. The majority of these methods look like this:&lt;br /&gt;
&lt;br /&gt;
 int [[aw_address]] (int session_id)&lt;br /&gt;
 {&lt;br /&gt;
   /* check if RC_NOT_INITIALIZED, RC_NO_INSTANCE or RC_NO_CONNECTION should be returned */&lt;br /&gt;
   ...&lt;br /&gt;
 &lt;br /&gt;
   /* send PACKET_GET_ADDRESS to the world server */&lt;br /&gt;
   ...&lt;br /&gt;
 &lt;br /&gt;
   /* &lt;br /&gt;
      if this is an asynchronous call then immediately return RC_SUCCESS indicating&lt;br /&gt;
      that the request has been _sent_ successfully.&lt;br /&gt;
   */&lt;br /&gt;
   if ([[aw_callback]] ([[AW_CALLBACK_ADDRESS]]) != NULL)&lt;br /&gt;
     return RC_SUCCESS;&lt;br /&gt;
 &lt;br /&gt;
   /*&lt;br /&gt;
      wait at most 18 seconds (or return RC_TIMEOUT) for a result to PACKET_ADDRESS to come&lt;br /&gt;
      in for the current instance processing all packets in the meantime, calling event and&lt;br /&gt;
      callback handlers.&lt;br /&gt;
   */&lt;br /&gt;
   return _aw_wait (18000, PACKET_ADDRESS); &lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
That blocking SDK methods can call event and callback handlers has implications. &amp;#039;&amp;#039;&amp;#039;The rule of thumb is:&amp;#039;&amp;#039;&amp;#039; Never place blocking SDK method calls in an event or callback handler. It requires in-depth knowledge to know when this is safe.&lt;br /&gt;
&lt;br /&gt;
For example, assume that a blocking call has been placed from within an event handler. If the event is triggered multiple times while the blocking call waits for a result then it will lead to the following problems:&lt;br /&gt;
&lt;br /&gt;
Problem #1:&lt;br /&gt;
:The first blocking call would call the event handler, which places a second blocking call. The second call must return before the first one can return. It is possible that the event is received again while the second call waits, which places a third blocking call. The third call must return before the second one can return. If more events than results are received then the call depth will increase.&lt;br /&gt;
&lt;br /&gt;
Problem #2:&lt;br /&gt;
:Assume that problem #1 occurs and leads to a big call depth. If less events than results are received then the call depth will decrease. There might be calls that will time-out due to having waited more than 18 seconds.&lt;br /&gt;
&lt;br /&gt;
Problem #3:&lt;br /&gt;
:Results will arrive in the same order that calls were placed. If there are multiple blocking calls waiting for results then the most recent call will receive the oldest result. &lt;br /&gt;
&lt;br /&gt;
==Arguments==&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;If &amp;lt;var&amp;gt;milliseconds&amp;lt;/var&amp;gt; is 0&amp;#039;&amp;#039;&amp;#039; then it will process any queued packets and return. This is typically used in single-threaded GUI applications. Where a timer is used to call this method repeatedly. A wait of around 100 ms (1000 / AW_MAX_AVCHANGE_PER_SECOND) or less between each call is recommended. See [http://msdn2.microsoft.com/en-us/library/ms644906.aspx SetTimer] for Windows applications.&lt;br /&gt;
&lt;br /&gt;
 void CALLBACK TimerProc (&lt;br /&gt;
     HWND hWnd,      // handle of window for timer messages&lt;br /&gt;
     UINT nMsg,      // WM_TIMER message&lt;br /&gt;
     UINT nIDEvent,  // timer identification&lt;br /&gt;
     DWORD dwTime)   // current system time&lt;br /&gt;
 {&lt;br /&gt;
   [[aw_wait]] (0); /* process any queued packets and return */&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 /* put this together with the rest of the intialization code */&lt;br /&gt;
 [[aw_init]] (AW_BUILD);&lt;br /&gt;
 SetTimer (NULL, 0, 100, TimerProc); /* call aw_wait at 100 millisecond intervals */&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;If &amp;lt;var&amp;gt;milliseconds&amp;lt;/var&amp;gt; is less than 0&amp;#039;&amp;#039;&amp;#039; then it will keep processing packets forever (or until [[aw_term]] is called, which is not recommended). This is typically used in simple console applications. Where any input comes through the SDK. In the form of events like [[AW_EVENT_CHAT|chat]], [[AW_EVENT_OBJECT_CLICK|object clicks]], and so forth.&lt;br /&gt;
&lt;br /&gt;
 [[aw_wait]] (-1); /* this will never return */&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;If &amp;lt;var&amp;gt;milliseconds&amp;lt;/var&amp;gt; is more than 0&amp;#039;&amp;#039;&amp;#039; then it will process packets until it that amount of time has passed (or until [[aw_term]] is called, which is not recommended). This makes it possible to periodically check for input from a user. Or to perform an action at certain intervals. For example, use [[aw_say]] to say something out loud every minute. Like this,&lt;br /&gt;
&lt;br /&gt;
 /* say &amp;quot;A minute has passed&amp;quot; every minute */&lt;br /&gt;
 while (1)&lt;br /&gt;
 {&lt;br /&gt;
   [[aw_wait]] (60000); /* wait 60,000 milliseconds, or 60 seconds */&lt;br /&gt;
   [[aw_say]] (&amp;quot;A minute has passed&amp;quot;);&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
This example checks for keyboard input at 100 millisecond intervals:&lt;br /&gt;
&lt;br /&gt;
 while (1)&lt;br /&gt;
 {&lt;br /&gt;
   [[aw_wait]] (100); /* wait 100 milliseconds */&lt;br /&gt;
   if (_kbhit ())&lt;br /&gt;
   {&lt;br /&gt;
     int ch = _getch ();&lt;br /&gt;
     &lt;br /&gt;
     /* if &amp;#039;q&amp;#039; was pressed then quit */&lt;br /&gt;
     if (_tolower (ch) == &amp;#039;q&amp;#039;)&lt;br /&gt;
       break;&lt;br /&gt;
     &lt;br /&gt;
     /* if &amp;#039;t&amp;#039; was pressed then print the tick count */&lt;br /&gt;
     if (_tolower (ch) == &amp;#039;t&amp;#039;)&lt;br /&gt;
       printf (&amp;quot;Ticks: %u\n&amp;quot;, [[aw_tick]] ());&lt;br /&gt;
   }&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Note, if [[aw_init]] has not been called (or [[aw_term]] has been called) then the call will return immediately.&lt;br /&gt;
&lt;br /&gt;
==Argument attributes==&lt;br /&gt;
None&lt;br /&gt;
&lt;br /&gt;
==Return values==&lt;br /&gt;
;[[SDK Reason Codes#RC_SUCCESS|RC_SUCCESS]]:&lt;br /&gt;
;[[SDK Reason Codes#RC_NOT_INITIALIZED|RC_NOT_INITIALIZED]]:If the milliseconds argument is 0 and aw_init has not been called (or aw_term has been called). &lt;br /&gt;
&lt;br /&gt;
==Returned attributes==&lt;br /&gt;
None&lt;br /&gt;
&lt;br /&gt;
==See also==&lt;br /&gt;
*[[SDK_Application_Structure|Application structure]]&lt;br /&gt;
*[[aw_event_set]]&lt;br /&gt;
*[[aw_callback_set]]&lt;br /&gt;
&lt;br /&gt;
[[Category: SDK Methods|W]]&lt;/div&gt;</summary>
		<author><name>Xan</name></author>
	</entry>
</feed>