+class _wxSocketInternalTimer: public wxTimer {
+ public:
+ int *m_state;
+ unsigned long m_new_val;
+
+ void Notify()
+ {
+ *m_state = m_new_val; // Change the value
+ }
+};
+
+int wxSocketBase::DeferRead(char *buffer, size_t nbytes)
+{
+ GSocketEventFlags old_event_flags;
+ bool old_notify_state;
+ // Timer for timeout
+ _wxSocketInternalTimer timer;
+
+ wxASSERT(m_defering == NO_DEFER);
+
+ // Set the defering mode to READ.
+ m_defering = DEFER_READ;
+
+ // Save the old state.
+ old_event_flags = NeededReq();
+ old_notify_state = m_notify_state;
+
+ // Set the new async flag.
+ SetNotify(GSOCK_INPUT_FLAG | GSOCK_LOST_FLAG);
+ Notify(TRUE);
+
+ // Set the current buffer.
+ m_defer_buffer = buffer;
+ m_defer_nbytes = nbytes;
+ m_defer_timer = &timer;
+
+ timer.m_state = (int *)&m_defer_buffer;
+ timer.m_new_val = 0;
+
+ timer.Start(m_timeout * 1000, FALSE);
+
+ // Wait for buffer completion.
+ while (m_defer_buffer != NULL)
+ wxYield();
+
+ timer.Stop();
+
+ // Restore the old state.
+ Notify(old_notify_state);
+ SetNotify(old_event_flags);
+
+ // Disable defering mode.
+ m_defering = NO_DEFER;
+ m_defer_timer = NULL;
+
+ // Return the number of bytes read from the socket.
+ return nbytes-m_defer_nbytes;
+}