]> git.saurik.com Git - wxWidgets.git/blob - src/common/socket.cpp
Fix InterruptWait on wxBase; use polling on wxBase (wxStopWatch is unavailable) and...
[wxWidgets.git] / src / common / socket.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: socket.cpp
3 // Purpose: Socket handler classes
4 // Authors: Guilhem Lavaux, Guillermo Rodriguez Garcia
5 // Created: April 1997
6 // Copyright: (C) 1999-1997, Guilhem Lavaux
7 // (C) 2000-1999, Guillermo Rodriguez Garcia
8 // RCS_ID: $Id$
9 // License: see wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // ==========================================================================
13 // Declarations
14 // ==========================================================================
15
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
18
19 #ifdef __BORLANDC__
20 #pragma hdrstop
21 #endif
22
23 #if wxUSE_SOCKETS
24
25 #include "wx/app.h"
26 #include "wx/apptrait.h"
27 #include "wx/defs.h"
28 #include "wx/object.h"
29 #include "wx/string.h"
30 #include "wx/timer.h"
31 #include "wx/utils.h"
32 #include "wx/module.h"
33 #include "wx/log.h"
34 #include "wx/intl.h"
35 #include "wx/event.h"
36
37 #include "wx/sckaddr.h"
38 #include "wx/socket.h"
39 #include "wx/datetime.h"
40
41 // DLL options compatibility check:
42 #include "wx/build.h"
43 WX_CHECK_BUILD_OPTIONS("wxNet")
44
45 // --------------------------------------------------------------------------
46 // macros and constants
47 // --------------------------------------------------------------------------
48
49 // discard buffer
50 #define MAX_DISCARD_SIZE (10 * 1024)
51
52 // what to do within waits: we have 2 cases: from the main thread itself we
53 // have to call wxYield() to let the events (including the GUI events and the
54 // low-level (not wxWidgets) events from GSocket) be processed. From another
55 // thread it is enough to just call wxThread::Yield() which will give away the
56 // rest of our time slice: the explanation is that the events will be processed
57 // by the main thread anyhow, without calling wxYield(), but we don't want to
58 // eat the CPU time uselessly while sitting in the loop waiting for the data
59 #if wxUSE_THREADS
60 #define PROCESS_EVENTS() \
61 { \
62 if ( wxThread::IsMain() ) \
63 wxYield(); \
64 else \
65 wxThread::Yield(); \
66 }
67 #else // !wxUSE_THREADS
68 #define PROCESS_EVENTS() wxYield()
69 #endif // wxUSE_THREADS/!wxUSE_THREADS
70
71 #define wxTRACE_Socket _T("wxSocket")
72
73 // --------------------------------------------------------------------------
74 // wxWin macros
75 // --------------------------------------------------------------------------
76
77 IMPLEMENT_CLASS(wxSocketBase, wxObject)
78 IMPLEMENT_CLASS(wxSocketServer, wxSocketBase)
79 IMPLEMENT_CLASS(wxSocketClient, wxSocketBase)
80 IMPLEMENT_CLASS(wxDatagramSocket, wxSocketBase)
81 IMPLEMENT_DYNAMIC_CLASS(wxSocketEvent, wxEvent)
82
83 // --------------------------------------------------------------------------
84 // private classes
85 // --------------------------------------------------------------------------
86
87 class wxSocketState : public wxObject
88 {
89 public:
90 wxSocketFlags m_flags;
91 wxSocketEventFlags m_eventmask;
92 bool m_notify;
93 void *m_clientData;
94
95 public:
96 wxSocketState() : wxObject() {}
97
98 DECLARE_NO_COPY_CLASS(wxSocketState)
99 };
100
101 // ==========================================================================
102 // wxSocketBase
103 // ==========================================================================
104
105 // --------------------------------------------------------------------------
106 // Initialization and shutdown
107 // --------------------------------------------------------------------------
108
109 // FIXME-MT: all this is MT-unsafe, of course, we should protect all accesses
110 // to m_countInit with a crit section
111 size_t wxSocketBase::m_countInit = 0;
112
113 bool wxSocketBase::IsInitialized()
114 {
115 return m_countInit > 0;
116 }
117
118 bool wxSocketBase::Initialize()
119 {
120 if ( !m_countInit++ )
121 {
122 /*
123 Details: Initialize() creates a hidden window as a sink for socket
124 events, such as 'read completed'. wxMSW has only one message loop
125 for the main thread. If Initialize is called in a secondary thread,
126 the socket window will be created for the secondary thread, but
127 since there is no message loop on this thread, it will never
128 receive events and all socket operations will time out.
129 BTW, the main thread must not be stopped using sleep or block
130 on a semaphore (a bad idea in any case) or socket operations
131 will time out.
132
133 On the Mac side, Initialize() stores a pointer to the CFRunLoop for
134 the main thread. Because secondary threads do not have run loops,
135 adding event notifications to the "Current" loop would have no
136 effect at all, events would never fire.
137 */
138 wxASSERT_MSG( wxIsMainThread(),
139 wxT("Call wxSocketBase::Initialize() from the main thread first!"));
140
141 wxAppTraits *traits = wxAppConsole::GetInstance() ?
142 wxAppConsole::GetInstance()->GetTraits() : NULL;
143 GSocketGUIFunctionsTable *functions =
144 traits ? traits->GetSocketGUIFunctionsTable() : NULL;
145 GSocket_SetGUIFunctions(functions);
146
147 if ( !GSocket_Init() )
148 {
149 m_countInit--;
150
151 return false;
152 }
153 }
154
155 return true;
156 }
157
158 void wxSocketBase::Shutdown()
159 {
160 // we should be initialized
161 wxASSERT_MSG( m_countInit, _T("extra call to Shutdown()") );
162 if ( !--m_countInit )
163 {
164 GSocket_Cleanup();
165 }
166 }
167
168 // --------------------------------------------------------------------------
169 // Ctor and dtor
170 // --------------------------------------------------------------------------
171
172 void wxSocketBase::Init()
173 {
174 m_socket = NULL;
175 m_type = wxSOCKET_UNINIT;
176
177 // state
178 m_flags = 0;
179 m_connected =
180 m_establishing =
181 m_reading =
182 m_writing =
183 m_error = false;
184 m_lcount = 0;
185 m_timeout = 600;
186 m_beingDeleted = false;
187
188 // pushback buffer
189 m_unread = NULL;
190 m_unrd_size = 0;
191 m_unrd_cur = 0;
192
193 // events
194 m_id = wxID_ANY;
195 m_handler = NULL;
196 m_clientData = NULL;
197 m_notify = false;
198 m_eventmask = 0;
199
200 if ( !IsInitialized() )
201 {
202 // this Initialize() will be undone by wxSocketModule::OnExit(), all the
203 // other calls to it should be matched by a call to Shutdown()
204 Initialize();
205 }
206 }
207
208 wxSocketBase::wxSocketBase()
209 {
210 Init();
211 }
212
213 wxSocketBase::wxSocketBase(wxSocketFlags flags, wxSocketType type)
214 {
215 Init();
216
217 m_flags = flags;
218 m_type = type;
219 }
220
221 wxSocketBase::~wxSocketBase()
222 {
223 // Just in case the app called Destroy() *and* then deleted
224 // the socket immediately: don't leave dangling pointers.
225 wxAppTraits *traits = wxTheApp ? wxTheApp->GetTraits() : NULL;
226 if ( traits )
227 traits->RemoveFromPendingDelete(this);
228
229 // Shutdown and close the socket
230 if (!m_beingDeleted)
231 Close();
232
233 // Destroy the GSocket object
234 if (m_socket)
235 delete m_socket;
236
237 // Free the pushback buffer
238 if (m_unread)
239 free(m_unread);
240 }
241
242 bool wxSocketBase::Destroy()
243 {
244 // Delayed destruction: the socket will be deleted during the next
245 // idle loop iteration. This ensures that all pending events have
246 // been processed.
247 m_beingDeleted = true;
248
249 // Shutdown and close the socket
250 Close();
251
252 // Supress events from now on
253 Notify(false);
254
255 // schedule this object for deletion
256 wxAppTraits *traits = wxTheApp ? wxTheApp->GetTraits() : NULL;
257 if ( traits )
258 {
259 // let the traits object decide what to do with us
260 traits->ScheduleForDestroy(this);
261 }
262 else // no app or no traits
263 {
264 // in wxBase we might have no app object at all, don't leak memory
265 delete this;
266 }
267
268 return true;
269 }
270
271 // --------------------------------------------------------------------------
272 // Basic IO calls
273 // --------------------------------------------------------------------------
274
275 // The following IO operations update m_error and m_lcount:
276 // {Read, Write, ReadMsg, WriteMsg, Peek, Unread, Discard}
277 //
278 // TODO: Should Connect, Accept and AcceptWith update m_error?
279
280 bool wxSocketBase::Close()
281 {
282 // Interrupt pending waits
283 InterruptWait();
284
285 if (m_socket)
286 {
287 // Disable callbacks
288 m_socket->UnsetCallback(GSOCK_INPUT_FLAG | GSOCK_OUTPUT_FLAG |
289 GSOCK_LOST_FLAG | GSOCK_CONNECTION_FLAG);
290
291 // Shutdown the connection
292 m_socket->Shutdown();
293 }
294
295 m_connected = false;
296 m_establishing = false;
297 return true;
298 }
299
300 wxSocketBase& wxSocketBase::Read(void* buffer, wxUint32 nbytes)
301 {
302 // Mask read events
303 m_reading = true;
304
305 m_lcount = _Read(buffer, nbytes);
306
307 // If in wxSOCKET_WAITALL mode, all bytes should have been read.
308 if (m_flags & wxSOCKET_WAITALL)
309 m_error = (m_lcount != nbytes);
310 else
311 m_error = (m_lcount == 0);
312
313 // Allow read events from now on
314 m_reading = false;
315
316 return *this;
317 }
318
319 wxUint32 wxSocketBase::_Read(void* buffer, wxUint32 nbytes)
320 {
321 int total;
322
323 // Try the pushback buffer first
324 total = GetPushback(buffer, nbytes, false);
325 nbytes -= total;
326 buffer = (char *)buffer + total;
327
328 // Return now in one of the following cases:
329 // - the socket is invalid,
330 // - we got all the data,
331 // - we got *some* data and we are not using wxSOCKET_WAITALL.
332 if ( !m_socket ||
333 !nbytes ||
334 ((total != 0) && !(m_flags & wxSOCKET_WAITALL)) )
335 return total;
336
337 // Possible combinations (they are checked in this order)
338 // wxSOCKET_NOWAIT
339 // wxSOCKET_WAITALL (with or without wxSOCKET_BLOCK)
340 // wxSOCKET_BLOCK
341 // wxSOCKET_NONE
342 //
343 int ret;
344 if (m_flags & wxSOCKET_NOWAIT)
345 {
346 m_socket->SetNonBlocking(1);
347 ret = m_socket->Read((char *)buffer, nbytes);
348 m_socket->SetNonBlocking(0);
349
350 if (ret > 0)
351 total += ret;
352 }
353 else
354 {
355 bool more = true;
356
357 while (more)
358 {
359 if ( !(m_flags & wxSOCKET_BLOCK) && !WaitForRead() )
360 break;
361
362 ret = m_socket->Read((char *)buffer, nbytes);
363
364 if (ret > 0)
365 {
366 total += ret;
367 nbytes -= ret;
368 buffer = (char *)buffer + ret;
369 }
370
371 // If we got here and wxSOCKET_WAITALL is not set, we can leave
372 // now. Otherwise, wait until we recv all the data or until there
373 // is an error.
374 //
375 more = (ret > 0 && nbytes > 0 && (m_flags & wxSOCKET_WAITALL));
376 }
377 }
378
379 return total;
380 }
381
382 wxSocketBase& wxSocketBase::ReadMsg(void* buffer, wxUint32 nbytes)
383 {
384 wxUint32 len, len2, sig, total;
385 bool error;
386 int old_flags;
387 struct
388 {
389 unsigned char sig[4];
390 unsigned char len[4];
391 } msg;
392
393 // Mask read events
394 m_reading = true;
395
396 total = 0;
397 error = true;
398 old_flags = m_flags;
399 SetFlags((m_flags & wxSOCKET_BLOCK) | wxSOCKET_WAITALL);
400
401 if (_Read(&msg, sizeof(msg)) != sizeof(msg))
402 goto exit;
403
404 sig = (wxUint32)msg.sig[0];
405 sig |= (wxUint32)(msg.sig[1] << 8);
406 sig |= (wxUint32)(msg.sig[2] << 16);
407 sig |= (wxUint32)(msg.sig[3] << 24);
408
409 if (sig != 0xfeeddead)
410 {
411 wxLogWarning(_("wxSocket: invalid signature in ReadMsg."));
412 goto exit;
413 }
414
415 len = (wxUint32)msg.len[0];
416 len |= (wxUint32)(msg.len[1] << 8);
417 len |= (wxUint32)(msg.len[2] << 16);
418 len |= (wxUint32)(msg.len[3] << 24);
419
420 if (len > nbytes)
421 {
422 len2 = len - nbytes;
423 len = nbytes;
424 }
425 else
426 len2 = 0;
427
428 // Don't attemp to read if the msg was zero bytes long.
429 if (len)
430 {
431 total = _Read(buffer, len);
432
433 if (total != len)
434 goto exit;
435 }
436 if (len2)
437 {
438 char *discard_buffer = new char[MAX_DISCARD_SIZE];
439 long discard_len;
440
441 // NOTE: discarded bytes don't add to m_lcount.
442 do
443 {
444 discard_len = ((len2 > MAX_DISCARD_SIZE)? MAX_DISCARD_SIZE : len2);
445 discard_len = _Read(discard_buffer, (wxUint32)discard_len);
446 len2 -= (wxUint32)discard_len;
447 }
448 while ((discard_len > 0) && len2);
449
450 delete [] discard_buffer;
451
452 if (len2 != 0)
453 goto exit;
454 }
455 if (_Read(&msg, sizeof(msg)) != sizeof(msg))
456 goto exit;
457
458 sig = (wxUint32)msg.sig[0];
459 sig |= (wxUint32)(msg.sig[1] << 8);
460 sig |= (wxUint32)(msg.sig[2] << 16);
461 sig |= (wxUint32)(msg.sig[3] << 24);
462
463 if (sig != 0xdeadfeed)
464 {
465 wxLogWarning(_("wxSocket: invalid signature in ReadMsg."));
466 goto exit;
467 }
468
469 // everything was OK
470 error = false;
471
472 exit:
473 m_error = error;
474 m_lcount = total;
475 m_reading = false;
476 SetFlags(old_flags);
477
478 return *this;
479 }
480
481 wxSocketBase& wxSocketBase::Peek(void* buffer, wxUint32 nbytes)
482 {
483 // Mask read events
484 m_reading = true;
485
486 m_lcount = _Read(buffer, nbytes);
487 Pushback(buffer, m_lcount);
488
489 // If in wxSOCKET_WAITALL mode, all bytes should have been read.
490 if (m_flags & wxSOCKET_WAITALL)
491 m_error = (m_lcount != nbytes);
492 else
493 m_error = (m_lcount == 0);
494
495 // Allow read events again
496 m_reading = false;
497
498 return *this;
499 }
500
501 wxSocketBase& wxSocketBase::Write(const void *buffer, wxUint32 nbytes)
502 {
503 // Mask write events
504 m_writing = true;
505
506 m_lcount = _Write(buffer, nbytes);
507
508 // If in wxSOCKET_WAITALL mode, all bytes should have been written.
509 if (m_flags & wxSOCKET_WAITALL)
510 m_error = (m_lcount != nbytes);
511 else
512 m_error = (m_lcount == 0);
513
514 // Allow write events again
515 m_writing = false;
516
517 return *this;
518 }
519
520 wxUint32 wxSocketBase::_Write(const void *buffer, wxUint32 nbytes)
521 {
522 wxUint32 total = 0;
523
524 // If the socket is invalid or parameters are ill, return immediately
525 if (!m_socket || !buffer || !nbytes)
526 return 0;
527
528 // Possible combinations (they are checked in this order)
529 // wxSOCKET_NOWAIT
530 // wxSOCKET_WAITALL (with or without wxSOCKET_BLOCK)
531 // wxSOCKET_BLOCK
532 // wxSOCKET_NONE
533 //
534 int ret;
535 if (m_flags & wxSOCKET_NOWAIT)
536 {
537 m_socket->SetNonBlocking(1);
538 ret = m_socket->Write((const char *)buffer, nbytes);
539 m_socket->SetNonBlocking(0);
540
541 if (ret > 0)
542 total = ret;
543 }
544 else
545 {
546 bool more = true;
547
548 while (more)
549 {
550 if ( !(m_flags & wxSOCKET_BLOCK) && !WaitForWrite() )
551 break;
552
553 ret = m_socket->Write((const char *)buffer, nbytes);
554
555 if (ret > 0)
556 {
557 total += ret;
558 nbytes -= ret;
559 buffer = (const char *)buffer + ret;
560 }
561
562 // If we got here and wxSOCKET_WAITALL is not set, we can leave
563 // now. Otherwise, wait until we send all the data or until there
564 // is an error.
565 //
566 more = (ret > 0 && nbytes > 0 && (m_flags & wxSOCKET_WAITALL));
567 }
568 }
569
570 return total;
571 }
572
573 wxSocketBase& wxSocketBase::WriteMsg(const void *buffer, wxUint32 nbytes)
574 {
575 wxUint32 total;
576 bool error;
577 struct
578 {
579 unsigned char sig[4];
580 unsigned char len[4];
581 } msg;
582
583 // Mask write events
584 m_writing = true;
585
586 error = true;
587 total = 0;
588 SetFlags((m_flags & wxSOCKET_BLOCK) | wxSOCKET_WAITALL);
589
590 msg.sig[0] = (unsigned char) 0xad;
591 msg.sig[1] = (unsigned char) 0xde;
592 msg.sig[2] = (unsigned char) 0xed;
593 msg.sig[3] = (unsigned char) 0xfe;
594
595 msg.len[0] = (unsigned char) (nbytes & 0xff);
596 msg.len[1] = (unsigned char) ((nbytes >> 8) & 0xff);
597 msg.len[2] = (unsigned char) ((nbytes >> 16) & 0xff);
598 msg.len[3] = (unsigned char) ((nbytes >> 24) & 0xff);
599
600 if (_Write(&msg, sizeof(msg)) < sizeof(msg))
601 goto exit;
602
603 total = _Write(buffer, nbytes);
604
605 if (total < nbytes)
606 goto exit;
607
608 msg.sig[0] = (unsigned char) 0xed;
609 msg.sig[1] = (unsigned char) 0xfe;
610 msg.sig[2] = (unsigned char) 0xad;
611 msg.sig[3] = (unsigned char) 0xde;
612 msg.len[0] = msg.len[1] = msg.len[2] = msg.len[3] = (char) 0;
613
614 if ((_Write(&msg, sizeof(msg))) < sizeof(msg))
615 goto exit;
616
617 // everything was OK
618 error = false;
619
620 exit:
621 m_error = error;
622 m_lcount = total;
623 m_writing = false;
624
625 return *this;
626 }
627
628 wxSocketBase& wxSocketBase::Unread(const void *buffer, wxUint32 nbytes)
629 {
630 if (nbytes != 0)
631 Pushback(buffer, nbytes);
632
633 m_error = false;
634 m_lcount = nbytes;
635
636 return *this;
637 }
638
639 wxSocketBase& wxSocketBase::Discard()
640 {
641 char *buffer = new char[MAX_DISCARD_SIZE];
642 wxUint32 ret;
643 wxUint32 total = 0;
644
645 // Mask read events
646 m_reading = true;
647
648 SetFlags(wxSOCKET_NOWAIT);
649
650 do
651 {
652 ret = _Read(buffer, MAX_DISCARD_SIZE);
653 total += ret;
654 }
655 while (ret == MAX_DISCARD_SIZE);
656
657 delete[] buffer;
658 m_lcount = total;
659 m_error = false;
660
661 // Allow read events again
662 m_reading = false;
663
664 return *this;
665 }
666
667 // --------------------------------------------------------------------------
668 // Wait functions
669 // --------------------------------------------------------------------------
670
671 // All Wait functions poll the socket using GSocket_Select() to
672 // check for the specified combination of conditions, until one
673 // of these conditions become true, an error occurs, or the
674 // timeout elapses. The polling loop calls PROCESS_EVENTS(), so
675 // this won't block the GUI.
676
677 bool wxSocketBase::_Wait(long seconds,
678 long milliseconds,
679 wxSocketEventFlags flags)
680 {
681 GSocketEventFlags result;
682 long timeout;
683
684 // Set this to true to interrupt ongoing waits
685 m_interrupt = false;
686
687 // Check for valid socket
688 if (!m_socket)
689 return false;
690
691 // Check for valid timeout value.
692 if (seconds != -1)
693 timeout = seconds * 1000 + milliseconds;
694 else
695 timeout = m_timeout * 1000;
696
697 // Wait in an active polling loop.
698 //
699 // NOTE: We duplicate some of the code in OnRequest, but this doesn't
700 // hurt. It has to be here because the (GSocket) event might arrive
701 // a bit delayed, and it has to be in OnRequest as well because we
702 // don't know whether the Wait functions are being used.
703 //
704 // Do this at least once (important if timeout == 0, when
705 // we are just polling). Also, if just polling, do not yield.
706
707 wxDateTime current_time = wxDateTime::UNow();
708 unsigned int time_limit = (current_time.GetTicks() * 1000) + current_time.GetMillisecond() + timeout;
709 bool done = false;
710 bool valid_result = false;
711
712 #if !defined(wxUSE_GUI) || !wxUSE_GUI
713 // This is used to avoid a busy loop on wxBase - having a select
714 // timeout of 50 ms per iteration should be enough.
715 if (timeout > 50)
716 m_socket->SetTimeout(50);
717 else
718 m_socket->SetTimeout(timeout);
719 #endif
720
721 while (!done)
722 {
723 result = m_socket->Select(flags | GSOCK_LOST_FLAG);
724
725 // Incoming connection (server) or connection established (client)
726 if (result & GSOCK_CONNECTION_FLAG)
727 {
728 m_connected = true;
729 m_establishing = false;
730 valid_result = true;
731 break;
732 }
733
734 // Data available or output buffer ready
735 if ((result & GSOCK_INPUT_FLAG) || (result & GSOCK_OUTPUT_FLAG))
736 {
737 valid_result = true;
738 break;
739 }
740
741 // Connection lost
742 if (result & GSOCK_LOST_FLAG)
743 {
744 m_connected = false;
745 m_establishing = false;
746 valid_result = ((flags & GSOCK_LOST_FLAG) != 0);
747 break;
748 }
749
750 // Wait more?
751 current_time = wxDateTime::UNow();
752 int time_left = time_limit - ((current_time.GetTicks() * 1000) + current_time.GetMillisecond());
753 if ((!timeout) || (time_left <= 0) || (m_interrupt))
754 done = true;
755 else
756 {
757 #if !defined(wxUSE_GUI) || !wxUSE_GUI
758 // If there's less than 50 ms left, just call select with that timeout.
759 if (time_left < 50)
760 m_socket->SetTimeout(time_left);
761 #else
762 PROCESS_EVENTS();
763 #endif
764 }
765 }
766
767 // Set timeout back to original value (we overwrote it for polling)
768 #if !defined(wxUSE_GUI) || !wxUSE_GUI
769 m_socket->SetTimeout(m_timeout*1000);
770 #endif
771
772 return valid_result;
773 }
774
775 bool wxSocketBase::Wait(long seconds, long milliseconds)
776 {
777 return _Wait(seconds, milliseconds, GSOCK_INPUT_FLAG |
778 GSOCK_OUTPUT_FLAG |
779 GSOCK_CONNECTION_FLAG |
780 GSOCK_LOST_FLAG);
781 }
782
783 bool wxSocketBase::WaitForRead(long seconds, long milliseconds)
784 {
785 // Check pushback buffer before entering _Wait
786 if (m_unread)
787 return true;
788
789 // Note that GSOCK_INPUT_LOST has to be explicitly passed to
790 // _Wait because of the semantics of WaitForRead: a return
791 // value of true means that a GSocket_Read call will return
792 // immediately, not that there is actually data to read.
793
794 return _Wait(seconds, milliseconds, GSOCK_INPUT_FLAG |
795 GSOCK_LOST_FLAG);
796 }
797
798
799 bool wxSocketBase::WaitForWrite(long seconds, long milliseconds)
800 {
801 return _Wait(seconds, milliseconds, GSOCK_OUTPUT_FLAG);
802 }
803
804 bool wxSocketBase::WaitForLost(long seconds, long milliseconds)
805 {
806 return _Wait(seconds, milliseconds, GSOCK_LOST_FLAG);
807 }
808
809 // --------------------------------------------------------------------------
810 // Miscellaneous
811 // --------------------------------------------------------------------------
812
813 //
814 // Get local or peer address
815 //
816
817 bool wxSocketBase::GetPeer(wxSockAddress& addr_man) const
818 {
819 GAddress *peer;
820
821 if (!m_socket)
822 return false;
823
824 peer = m_socket->GetPeer();
825
826 // copying a null address would just trigger an assert anyway
827
828 if (!peer)
829 return false;
830
831 addr_man.SetAddress(peer);
832 GAddress_destroy(peer);
833
834 return true;
835 }
836
837 bool wxSocketBase::GetLocal(wxSockAddress& addr_man) const
838 {
839 GAddress *local;
840
841 if (!m_socket)
842 return false;
843
844 local = m_socket->GetLocal();
845 addr_man.SetAddress(local);
846 GAddress_destroy(local);
847
848 return true;
849 }
850
851 //
852 // Save and restore socket state
853 //
854
855 void wxSocketBase::SaveState()
856 {
857 wxSocketState *state;
858
859 state = new wxSocketState();
860
861 state->m_flags = m_flags;
862 state->m_notify = m_notify;
863 state->m_eventmask = m_eventmask;
864 state->m_clientData = m_clientData;
865
866 m_states.Append(state);
867 }
868
869 void wxSocketBase::RestoreState()
870 {
871 wxList::compatibility_iterator node;
872 wxSocketState *state;
873
874 node = m_states.GetLast();
875 if (!node)
876 return;
877
878 state = (wxSocketState *)node->GetData();
879
880 m_flags = state->m_flags;
881 m_notify = state->m_notify;
882 m_eventmask = state->m_eventmask;
883 m_clientData = state->m_clientData;
884
885 m_states.Erase(node);
886 delete state;
887 }
888
889 //
890 // Timeout and flags
891 //
892
893 void wxSocketBase::SetTimeout(long seconds)
894 {
895 m_timeout = seconds;
896
897 if (m_socket)
898 m_socket->SetTimeout(m_timeout * 1000);
899 }
900
901 void wxSocketBase::SetFlags(wxSocketFlags flags)
902 {
903 m_flags = flags;
904 }
905
906
907 // --------------------------------------------------------------------------
908 // Event handling
909 // --------------------------------------------------------------------------
910
911 // A note on how events are processed, which is probably the most
912 // difficult thing to get working right while keeping the same API
913 // and functionality for all platforms.
914 //
915 // When GSocket detects an event, it calls wx_socket_callback, which in
916 // turn just calls wxSocketBase::OnRequest in the corresponding wxSocket
917 // object. OnRequest does some housekeeping, and if the event is to be
918 // propagated to the user, it creates a new wxSocketEvent object and
919 // posts it. The event is not processed immediately, but delayed with
920 // AddPendingEvent instead. This is necessary in order to decouple the
921 // event processing from wx_socket_callback; otherwise, subsequent IO
922 // calls made from the user event handler would fail, as gtk callbacks
923 // are not reentrant.
924 //
925 // Note that, unlike events, user callbacks (now deprecated) are _not_
926 // decoupled from wx_socket_callback and thus they suffer from a variety
927 // of problems. Avoid them where possible and use events instead.
928
929 extern "C"
930 void LINKAGEMODE wx_socket_callback(GSocket * WXUNUSED(socket),
931 GSocketEvent notification,
932 char *cdata)
933 {
934 wxSocketBase *sckobj = (wxSocketBase *)cdata;
935
936 sckobj->OnRequest((wxSocketNotify) notification);
937 }
938
939 void wxSocketBase::OnRequest(wxSocketNotify notification)
940 {
941 // NOTE: We duplicate some of the code in _Wait, but this doesn't
942 // hurt. It has to be here because the (GSocket) event might arrive
943 // a bit delayed, and it has to be in _Wait as well because we don't
944 // know whether the Wait functions are being used.
945
946 switch(notification)
947 {
948 case wxSOCKET_CONNECTION:
949 m_establishing = false;
950 m_connected = true;
951 break;
952
953 // If we are in the middle of a R/W operation, do not
954 // propagate events to users. Also, filter 'late' events
955 // which are no longer valid.
956
957 case wxSOCKET_INPUT:
958 if (m_reading || !m_socket->Select(GSOCK_INPUT_FLAG))
959 return;
960 break;
961
962 case wxSOCKET_OUTPUT:
963 if (m_writing || !m_socket->Select(GSOCK_OUTPUT_FLAG))
964 return;
965 break;
966
967 case wxSOCKET_LOST:
968 m_connected = false;
969 m_establishing = false;
970 break;
971
972 default:
973 break;
974 }
975
976 // Schedule the event
977
978 wxSocketEventFlags flag = 0;
979 wxUnusedVar(flag);
980 switch (notification)
981 {
982 case GSOCK_INPUT: flag = GSOCK_INPUT_FLAG; break;
983 case GSOCK_OUTPUT: flag = GSOCK_OUTPUT_FLAG; break;
984 case GSOCK_CONNECTION: flag = GSOCK_CONNECTION_FLAG; break;
985 case GSOCK_LOST: flag = GSOCK_LOST_FLAG; break;
986 default:
987 wxLogWarning(_("wxSocket: unknown event!."));
988 return;
989 }
990
991 if (((m_eventmask & flag) == flag) && m_notify)
992 {
993 if (m_handler)
994 {
995 wxSocketEvent event(m_id);
996 event.m_event = notification;
997 event.m_clientData = m_clientData;
998 event.SetEventObject(this);
999
1000 m_handler->AddPendingEvent(event);
1001 }
1002 }
1003 }
1004
1005 void wxSocketBase::Notify(bool notify)
1006 {
1007 m_notify = notify;
1008 }
1009
1010 void wxSocketBase::SetNotify(wxSocketEventFlags flags)
1011 {
1012 m_eventmask = flags;
1013 }
1014
1015 void wxSocketBase::SetEventHandler(wxEvtHandler& handler, int id)
1016 {
1017 m_handler = &handler;
1018 m_id = id;
1019 }
1020
1021 // --------------------------------------------------------------------------
1022 // Pushback buffer
1023 // --------------------------------------------------------------------------
1024
1025 void wxSocketBase::Pushback(const void *buffer, wxUint32 size)
1026 {
1027 if (!size) return;
1028
1029 if (m_unread == NULL)
1030 m_unread = malloc(size);
1031 else
1032 {
1033 void *tmp;
1034
1035 tmp = malloc(m_unrd_size + size);
1036 memcpy((char *)tmp + size, m_unread, m_unrd_size);
1037 free(m_unread);
1038
1039 m_unread = tmp;
1040 }
1041
1042 m_unrd_size += size;
1043
1044 memcpy(m_unread, buffer, size);
1045 }
1046
1047 wxUint32 wxSocketBase::GetPushback(void *buffer, wxUint32 size, bool peek)
1048 {
1049 if (!m_unrd_size)
1050 return 0;
1051
1052 if (size > (m_unrd_size-m_unrd_cur))
1053 size = m_unrd_size-m_unrd_cur;
1054
1055 memcpy(buffer, (char *)m_unread + m_unrd_cur, size);
1056
1057 if (!peek)
1058 {
1059 m_unrd_cur += size;
1060 if (m_unrd_size == m_unrd_cur)
1061 {
1062 free(m_unread);
1063 m_unread = NULL;
1064 m_unrd_size = 0;
1065 m_unrd_cur = 0;
1066 }
1067 }
1068
1069 return size;
1070 }
1071
1072
1073 // ==========================================================================
1074 // wxSocketServer
1075 // ==========================================================================
1076
1077 // --------------------------------------------------------------------------
1078 // Ctor
1079 // --------------------------------------------------------------------------
1080
1081 wxSocketServer::wxSocketServer(const wxSockAddress& addr_man,
1082 wxSocketFlags flags)
1083 : wxSocketBase(flags, wxSOCKET_SERVER)
1084 {
1085 wxLogTrace( wxTRACE_Socket, _T("Opening wxSocketServer") );
1086
1087 m_socket = GSocket_new();
1088
1089 if (!m_socket)
1090 {
1091 wxLogTrace( wxTRACE_Socket, _T("*** GSocket_new failed") );
1092 return;
1093 }
1094
1095 // Setup the socket as server
1096
1097 m_socket->SetLocal(addr_man.GetAddress());
1098
1099 if (GetFlags() & wxSOCKET_REUSEADDR) {
1100 m_socket->SetReusable();
1101 }
1102
1103 if (m_socket->SetServer() != GSOCK_NOERROR)
1104 {
1105 delete m_socket;
1106 m_socket = NULL;
1107
1108 wxLogTrace( wxTRACE_Socket, _T("*** GSocket_SetServer failed") );
1109 return;
1110 }
1111
1112 m_socket->SetTimeout(m_timeout * 1000);
1113 m_socket->SetCallback(GSOCK_INPUT_FLAG | GSOCK_OUTPUT_FLAG |
1114 GSOCK_LOST_FLAG | GSOCK_CONNECTION_FLAG,
1115 wx_socket_callback, (char *)this);
1116 }
1117
1118 // --------------------------------------------------------------------------
1119 // Accept
1120 // --------------------------------------------------------------------------
1121
1122 bool wxSocketServer::AcceptWith(wxSocketBase& sock, bool wait)
1123 {
1124 GSocket *child_socket;
1125
1126 if (!m_socket)
1127 return false;
1128
1129 // If wait == false, then the call should be nonblocking.
1130 // When we are finished, we put the socket to blocking mode
1131 // again.
1132
1133 if (!wait)
1134 m_socket->SetNonBlocking(1);
1135
1136 child_socket = m_socket->WaitConnection();
1137
1138 if (!wait)
1139 m_socket->SetNonBlocking(0);
1140
1141 if (!child_socket)
1142 return false;
1143
1144 sock.m_type = wxSOCKET_BASE;
1145 sock.m_socket = child_socket;
1146 sock.m_connected = true;
1147
1148 sock.m_socket->SetTimeout(sock.m_timeout * 1000);
1149 sock.m_socket->SetCallback(GSOCK_INPUT_FLAG | GSOCK_OUTPUT_FLAG |
1150 GSOCK_LOST_FLAG | GSOCK_CONNECTION_FLAG,
1151 wx_socket_callback, (char *)&sock);
1152
1153 return true;
1154 }
1155
1156 wxSocketBase *wxSocketServer::Accept(bool wait)
1157 {
1158 wxSocketBase* sock = new wxSocketBase();
1159
1160 sock->SetFlags(m_flags);
1161
1162 if (!AcceptWith(*sock, wait))
1163 {
1164 sock->Destroy();
1165 sock = NULL;
1166 }
1167
1168 return sock;
1169 }
1170
1171 bool wxSocketServer::WaitForAccept(long seconds, long milliseconds)
1172 {
1173 return _Wait(seconds, milliseconds, GSOCK_CONNECTION_FLAG);
1174 }
1175
1176 bool wxSocketBase::GetOption(int level, int optname, void *optval, int *optlen)
1177 {
1178 wxASSERT_MSG( m_socket, _T("Socket not initialised") );
1179
1180 if (m_socket->GetSockOpt(level, optname, optval, optlen)
1181 != GSOCK_NOERROR)
1182 {
1183 return false;
1184 }
1185 return true;
1186 }
1187
1188 bool wxSocketBase::SetOption(int level, int optname, const void *optval,
1189 int optlen)
1190 {
1191 wxASSERT_MSG( m_socket, _T("Socket not initialised") );
1192
1193 if (m_socket->SetSockOpt(level, optname, optval, optlen)
1194 != GSOCK_NOERROR)
1195 {
1196 return false;
1197 }
1198 return true;
1199 }
1200
1201 // ==========================================================================
1202 // wxSocketClient
1203 // ==========================================================================
1204
1205 // --------------------------------------------------------------------------
1206 // Ctor and dtor
1207 // --------------------------------------------------------------------------
1208
1209 wxSocketClient::wxSocketClient(wxSocketFlags flags)
1210 : wxSocketBase(flags, wxSOCKET_CLIENT)
1211 {
1212 }
1213
1214 wxSocketClient::~wxSocketClient()
1215 {
1216 }
1217
1218 // --------------------------------------------------------------------------
1219 // Connect
1220 // --------------------------------------------------------------------------
1221
1222 bool wxSocketClient::Connect(wxSockAddress& addr_man, bool wait)
1223 {
1224 GSocketError err;
1225
1226 if (m_socket)
1227 {
1228 // Shutdown and destroy the socket
1229 Close();
1230 delete m_socket;
1231 }
1232
1233 m_socket = GSocket_new();
1234 m_connected = false;
1235 m_establishing = false;
1236
1237 if (!m_socket)
1238 return false;
1239
1240 m_socket->SetTimeout(m_timeout * 1000);
1241 m_socket->SetCallback(GSOCK_INPUT_FLAG | GSOCK_OUTPUT_FLAG |
1242 GSOCK_LOST_FLAG | GSOCK_CONNECTION_FLAG,
1243 wx_socket_callback, (char *)this);
1244
1245 // If wait == false, then the call should be nonblocking.
1246 // When we are finished, we put the socket to blocking mode
1247 // again.
1248
1249 if (!wait)
1250 m_socket->SetNonBlocking(1);
1251
1252 m_socket->SetPeer(addr_man.GetAddress());
1253 err = m_socket->Connect(GSOCK_STREAMED);
1254
1255 if (!wait)
1256 m_socket->SetNonBlocking(0);
1257
1258 if (err != GSOCK_NOERROR)
1259 {
1260 if (err == GSOCK_WOULDBLOCK)
1261 m_establishing = true;
1262
1263 return false;
1264 }
1265
1266 m_connected = true;
1267 return true;
1268 }
1269
1270 bool wxSocketClient::WaitOnConnect(long seconds, long milliseconds)
1271 {
1272 if (m_connected) // Already connected
1273 return true;
1274
1275 if (!m_establishing || !m_socket) // No connection in progress
1276 return false;
1277
1278 return _Wait(seconds, milliseconds, GSOCK_CONNECTION_FLAG |
1279 GSOCK_LOST_FLAG);
1280 }
1281
1282 // ==========================================================================
1283 // wxDatagramSocket
1284 // ==========================================================================
1285
1286 /* NOTE: experimental stuff - might change */
1287
1288 wxDatagramSocket::wxDatagramSocket( const wxSockAddress& addr,
1289 wxSocketFlags flags )
1290 : wxSocketBase( flags, wxSOCKET_DATAGRAM )
1291 {
1292 // Create the socket
1293 m_socket = GSocket_new();
1294
1295 if(!m_socket)
1296 {
1297 wxASSERT_MSG( 0, _T("datagram socket not new'd") );
1298 return;
1299 }
1300 // Setup the socket as non connection oriented
1301 m_socket->SetLocal(addr.GetAddress());
1302 if( m_socket->SetNonOriented() != GSOCK_NOERROR )
1303 {
1304 delete m_socket;
1305 m_socket = NULL;
1306 return;
1307 }
1308
1309 // Initialize all stuff
1310 m_connected = false;
1311 m_establishing = false;
1312 m_socket->SetTimeout( m_timeout );
1313 m_socket->SetCallback( GSOCK_INPUT_FLAG | GSOCK_OUTPUT_FLAG |
1314 GSOCK_LOST_FLAG | GSOCK_CONNECTION_FLAG,
1315 wx_socket_callback, (char*)this );
1316
1317 }
1318
1319 wxDatagramSocket& wxDatagramSocket::RecvFrom( wxSockAddress& addr,
1320 void* buf,
1321 wxUint32 nBytes )
1322 {
1323 Read(buf, nBytes);
1324 GetPeer(addr);
1325 return (*this);
1326 }
1327
1328 wxDatagramSocket& wxDatagramSocket::SendTo( const wxSockAddress& addr,
1329 const void* buf,
1330 wxUint32 nBytes )
1331 {
1332 wxASSERT_MSG( m_socket, _T("Socket not initialised") );
1333
1334 m_socket->SetPeer(addr.GetAddress());
1335 Write(buf, nBytes);
1336 return (*this);
1337 }
1338
1339 // ==========================================================================
1340 // wxSocketModule
1341 // ==========================================================================
1342
1343 class wxSocketModule : public wxModule
1344 {
1345 public:
1346 virtual bool OnInit()
1347 {
1348 // wxSocketBase will call GSocket_Init() itself when/if needed
1349 return true;
1350 }
1351
1352 virtual void OnExit()
1353 {
1354 if ( wxSocketBase::IsInitialized() )
1355 wxSocketBase::Shutdown();
1356 }
1357
1358 private:
1359 DECLARE_DYNAMIC_CLASS(wxSocketModule)
1360 };
1361
1362 IMPLEMENT_DYNAMIC_CLASS(wxSocketModule, wxModule)
1363
1364 #endif
1365 // wxUSE_SOCKETS
1366
1367 // vi:sts=4:sw=4:et