]> git.saurik.com Git - wxWidgets.git/blob - src/common/socket.cpp
Some stubs includes removed from wxMotif; wxNotebook sample hack to make it display;
[wxWidgets.git] / src / common / socket.cpp
1 ////////////////////////////////////////////////////////////////////////////////
2 // Name: socket.cpp
3 // Purpose: Socket handler classes
4 // Authors: Guilhem Lavaux (completely rewritten from a basic API of Andrew
5 // Davidson(1995) in wxWeb)
6 // Created: April 1997
7 // Updated: March 1998
8 // Copyright: (C) 1998, 1997, Guilhem Lavaux
9 // RCS_ID: $Id$
10 // License: see wxWindows license
11 ////////////////////////////////////////////////////////////////////////////////
12 #ifdef __GNUG__
13 #pragma implementation "socket.h"
14 // #pragma interface
15 // #pragma implementation "socket.cpp"
16 #endif
17
18 // For compilers that support precompilation, includes "wx.h".
19 #include "wx/wxprec.h"
20
21 #ifdef __BORLANDC__
22 #pragma hdrstop
23 #endif
24
25 /////////////////////////////////////////////////////////////////////////////
26 // wxWindows headers
27 /////////////////////////////////////////////////////////////////////////////
28 #include <wx/defs.h>
29 #include <wx/object.h>
30 #include <wx/string.h>
31 #include <wx/timer.h>
32 #include <wx/utils.h>
33
34 // Not enough OS behaviour defined for wxStubs
35 #ifndef __WXSTUBS__
36
37 #include <stdlib.h>
38 #include <string.h>
39 #include <ctype.h>
40
41 /////////////////////////////////////////////////////////////////////////////
42 // System specific headers
43 /////////////////////////////////////////////////////////////////////////////
44 #if defined(__WINDOWS__)
45 #include <winsock.h>
46 #endif // __WINDOWS__
47
48 #if defined(__UNIX__)
49
50 #ifdef VMS
51 #include <socket.h>
52 #else
53 #include <sys/socket.h>
54 #endif
55 #include <sys/ioctl.h>
56
57 #include <sys/time.h>
58 #include <unistd.h>
59
60 #ifdef sun
61 #include <sys/filio.h>
62 #endif
63
64 #endif // __UNIX__
65
66 #include <signal.h>
67 #include <errno.h>
68
69 #ifdef _MSC_VER
70 #include <io.h>
71 #endif
72
73 #if defined(__WXMOTIF__) || defined(__WXXT__)
74 #include <X11/Intrinsic.h>
75
76 /////////////////////////////
77 // Needs internal variables
78 /////////////////////////////
79 #ifdef __WXXT__
80 #define Uses_XtIntrinsic
81 #endif
82
83 #endif
84
85 #if defined(__WXGTK__)
86 #include <gtk/gtk.h>
87 #endif
88
89 /////////////////////////////////////////////////////////////////////////////
90 // wxSocket headers
91 /////////////////////////////////////////////////////////////////////////////
92 #include "wx/module.h"
93 #define WXSOCK_INTERNAL
94 #include "wx/sckaddr.h"
95 #include "wx/socket.h"
96
97 /////////////////////////////////////////////////////////////////////////////
98 // Some patch ///// BEGIN
99 /////////////////////////////////////////////////////////////////////////////
100 #ifdef __WINDOWS__
101 #define close closesocket
102 #define ioctl ioctlsocket
103 #ifdef errno
104 #undef errno
105 #endif
106 #define errno WSAGetLastError()
107 #ifdef EWOULDBLOCK
108 #undef EWOULDBLOCK
109 #endif
110 #define EWOULDBLOCK WSAEWOULDBLOCK
111 #define ETIMEDOUT WSAETIMEDOUT
112 #undef EINTR
113 #define EINTR WSAEINTR
114 #endif
115
116 #ifndef __WINDOWS__
117 #define INVALID_SOCKET -1
118 #endif
119
120 #ifdef __WXMOTIF__
121 #define wxAPP_CONTEXT ((XtAppContext)wxTheApp->GetAppContext())
122 #endif
123
124 #ifdef __WINDOWS__
125 // This is an MS TCP/IP routine and is not needed here. Some WinSock
126 // implementations (such as PC-NFS) will require you to include this
127 // or a similar routine (see appendix in WinSock doc or help file).
128
129 #if defined( NEED_WSAFDIsSet ) || defined( _MSC_VER )
130 int PASCAL FAR __WSAFDIsSet(SOCKET fd, fd_set FAR *set)
131 {
132 int i = set->fd_count;
133
134 while (i--)
135 {
136 if (set->fd_array[i] == fd)
137 return 1;
138 }
139
140 return 0;
141 }
142 #endif
143 #endif
144
145 #if defined(__WINDOWS__)
146 #define PROCESS_EVENTS() wxYield()
147 #elif defined(__WXXT__) || defined(__WXMOTIF__)
148 #define PROCESS_EVENTS() XtAppProcessEvent(wxAPP_CONTEXT, XtIMAll)
149 #elif defined(__WXGTK__)
150 #define PROCESS_EVENTS() gtk_main_iteration()
151 #endif
152
153 /////////////////////////////////////////////////////////////////////////////
154 // Some patch ///// END
155 /////////////////////////////////////////////////////////////////////////////
156
157 // --------------------------------------------------------------
158 // Module
159 // --------------------------------------------------------------
160 class wxSocketModule: public wxModule {
161 DECLARE_DYNAMIC_CLASS(wxSocketModule)
162 public:
163 wxSocketModule() {}
164 bool OnInit();
165 void OnExit();
166 };
167
168 // --------------------------------------------------------------
169 // ClassInfos
170 // --------------------------------------------------------------
171 #if !USE_SHARED_LIBRARY
172 IMPLEMENT_CLASS(wxSocketBase, wxObject)
173 IMPLEMENT_CLASS(wxSocketServer, wxSocketBase)
174 IMPLEMENT_CLASS(wxSocketClient, wxSocketBase)
175 IMPLEMENT_CLASS(wxSocketHandler, wxObject)
176 IMPLEMENT_DYNAMIC_CLASS(wxSocketEvent, wxEvent)
177 IMPLEMENT_DYNAMIC_CLASS(wxSocketModule, wxModule)
178 #endif
179
180 class wxSockWakeUp : public wxTimer {
181 public:
182 int *my_id;
183 int n_val;
184 wxSocketBase *sock;
185
186 wxSockWakeUp(wxSocketBase *_sock, int *id, int new_val) {
187 my_id = id; n_val = new_val;
188 sock = _sock;
189 }
190 virtual void Notify() {
191 *my_id = n_val;
192 if (sock) sock->Notify(FALSE);
193 }
194 };
195
196 /// Socket request
197 class SockRequest : public wxObject {
198 public:
199 char *buffer;
200 size_t size, nbytes;
201 bool done;
202 int error;
203 wxSockWakeUp *auto_wakeup;
204 wxSocketBase::wxRequestNotify type;
205 };
206
207
208 /////////////////////////////////////////////////////////////////////////////
209 // Some internal define
210 /////////////////////////////////////////////////////////////////////////////
211
212 // --------------------------------------------------------------
213 // --------- wxSocketBase CONSTRUCTOR ---------------------------
214 // --------------------------------------------------------------
215 wxSocketBase::wxSocketBase(wxSocketBase::wxSockFlags _flags,
216 wxSocketBase::wxSockType _type) :
217 wxEvtHandler(),
218 m_flags(_flags), m_type(_type), m_connected(FALSE), m_connecting(FALSE),
219 m_fd(INVALID_SOCKET), m_waitflags(0), m_cbk(0), m_cdata(0), m_id(-1),
220 m_handler(0),
221 m_neededreq((wxRequestNotify)(REQ_READ | REQ_LOST)),
222 m_cbkon(FALSE),
223 m_unread(NULL), m_unrd_size(0),
224 m_processing(FALSE),
225 m_timeout(3600), m_wantbuf(0)
226 {
227 m_internal = new wxSockInternal;
228 #if defined(__WXXT__) || defined(__WXMOTIF__) || defined(__WXGTK__)
229 m_internal->sock_inputid = 0;
230 m_internal->sock_outputid = 0;
231 m_internal->sock_exceptid = 0;
232 #endif
233 #ifdef __WINDOWS__
234 m_internal->my_msg = 0;
235 #endif
236 }
237
238 wxSocketBase::wxSocketBase() :
239 wxEvtHandler(),
240 m_flags(WAITALL), m_type(SOCK_UNINIT), m_connected(FALSE),
241 m_connecting(FALSE), m_fd(INVALID_SOCKET), m_waitflags(0),
242 m_cbk(0), m_cdata(0),
243 m_id(-1), m_handler(0),
244 m_neededreq((wxRequestNotify)(REQ_READ | REQ_LOST)),
245 m_cbkon(FALSE),
246 m_unread(NULL), m_unrd_size(0),
247 m_processing(FALSE),
248 m_timeout(3600), m_wantbuf(0)
249 {
250 m_internal = new wxSockInternal;
251 #if defined(__WXXT__) || defined(__WXMOTIF__) || defined(__WXGTK__)
252 m_internal->sock_inputid = 0;
253 m_internal->sock_outputid = 0;
254 m_internal->sock_exceptid = 0;
255 #endif
256 #ifdef __WINDOWS__
257 m_internal->my_msg = 0;
258 #endif
259 }
260
261 // --------------------------------------------------------------
262 // --------- wxSocketBase CONSTRUCTOR ---------------------------
263 // --------------------------------------------------------------
264 wxSocketBase::~wxSocketBase()
265 {
266 DestroyCallbacks();
267 Close();
268
269 if (m_unread)
270 free(m_unread);
271 if (m_handler) {
272 #ifdef __WINDOWS__
273 if (m_internal->my_msg)
274 m_handler->DestroyMessage(m_internal->my_msg);
275 #endif
276 m_handler->UnRegister(this);
277 }
278 m_states.DeleteContents(TRUE);
279
280 delete m_internal;
281 }
282
283 bool wxSocketBase::Close()
284 {
285 if (m_fd != INVALID_SOCKET) {
286 for (int i=0;i<3;i++) {
287 wxNode *n, *node = req_list[i].First();
288
289 while (node) {
290 SockRequest *req = (SockRequest *)node->Data();
291 req->done = TRUE;
292
293 n = node->Next();
294 delete node;
295 node = n;
296 }
297 }
298
299 DestroyCallbacks();
300 shutdown(m_fd, 2);
301 close(m_fd);
302 m_fd = INVALID_SOCKET;
303 m_connected = FALSE;
304 }
305
306 return TRUE;
307 }
308
309 // --------------------------------------------------------------
310 // --------- wxSocketBase base IO functions ---------------------
311 // --------------------------------------------------------------
312 wxSocketBase& wxSocketBase::Read(char* buffer, size_t nbytes)
313 {
314 m_lcount = GetPushback(buffer, nbytes, FALSE);
315
316 // If we have got the whole needed buffer or if we don't want to
317 // wait then it returns immediately.
318 if (!nbytes || (m_lcount && !(m_flags & WAITALL)) )
319 return *this;
320
321 WantBuffer(buffer, nbytes, EVT_READ);
322
323 return *this;
324 }
325
326 wxSocketBase& wxSocketBase::Peek(char* buffer, size_t nbytes)
327 {
328 size_t nbytes_old = nbytes;
329
330 nbytes -= GetPushback(buffer, nbytes, TRUE);
331 if (!nbytes) {
332 m_lcount = nbytes_old;
333 return *this;
334 }
335
336 WantBuffer(buffer, nbytes, EVT_PEEK);
337
338 return *this;
339 }
340
341 wxSocketBase& wxSocketBase::Write(const char *buffer, size_t nbytes)
342 {
343 WantBuffer((char *)buffer, nbytes, EVT_WRITE);
344 return *this;
345 }
346
347 wxSocketBase& wxSocketBase::ReadMsg(char* buffer, size_t nbytes)
348 {
349 SockMsg msg;
350 size_t len, len2, sig;
351
352 Read((char *)&msg, sizeof(msg));
353 if (m_lcount != sizeof(msg))
354 return *this;
355
356 sig = msg.sig[0] & 0xff;
357 sig |= (size_t)(msg.sig[1] & 0xff) << 8;
358 sig |= (size_t)(msg.sig[2] & 0xff) << 16;
359 sig |= (size_t)(msg.sig[3] & 0xff) << 24;
360
361 if (sig != 0xfeeddead)
362 return *this;
363 len = msg.len[0] & 0xff;
364 len |= (size_t)(msg.len[1] & 0xff) << 8;
365 len |= (size_t)(msg.len[2] & 0xff) << 16;
366 len |= (size_t)(msg.len[3] & 0xff) << 24;
367 len2 = len;
368 if (len > nbytes)
369 len = nbytes;
370 else
371 len2 = 0;
372
373 if (Read(buffer, len).LastCount() != len)
374 return *this;
375 if (len2 && (Read(NULL, len2).LastCount() != len2))
376 return *this;
377 if (Read((char *)&msg, sizeof(msg)).LastCount() != sizeof(msg))
378 return *this;
379
380 sig = msg.sig[0] & 0xff;
381 sig |= (size_t)(msg.sig[1] & 0xff) << 8;
382 sig |= (size_t)(msg.sig[2] & 0xff) << 16;
383 sig |= (size_t)(msg.sig[3] & 0xff) << 24;
384 // ERROR
385 if (sig != 0xdeadfeed)
386 return *this;
387
388 return *this;
389 }
390
391 wxSocketBase& wxSocketBase::WriteMsg(const char *buffer, size_t nbytes)
392 {
393 SockMsg msg;
394
395 msg.sig[0] = (char) 0xad;
396 msg.sig[1] = (char) 0xde;
397 msg.sig[2] = (char) 0xed;
398 msg.sig[3] = (char) 0xfe;
399
400 msg.len[0] = (char) nbytes & 0xff;
401 msg.len[1] = (char) (nbytes >> 8) & 0xff;
402 msg.len[2] = (char) (nbytes >> 16) & 0xff;
403 msg.len[3] = (char) (nbytes >> 24) & 0xff;
404
405 if (Write((char *)&msg, sizeof(msg)).LastCount() < sizeof(msg))
406 return *this;
407 if (Write(buffer, nbytes).LastCount() < nbytes)
408 return *this;
409
410 msg.sig[0] = (char) 0xed;
411 msg.sig[1] = (char) 0xfe;
412 msg.sig[2] = (char) 0xad;
413 msg.sig[3] = (char) 0xde;
414 msg.len[0] = msg.len[1] = msg.len[2] = msg.len[3] = (char) 0;
415 Write((char *)&msg, sizeof(msg));
416
417 return *this;
418 }
419
420 wxSocketBase& wxSocketBase::Unread(const char *buffer, size_t nbytes)
421 {
422 CreatePushbackAfter(buffer, nbytes);
423 return *this;
424 }
425
426 bool wxSocketBase::IsData() const
427 {
428 struct timeval tv;
429 fd_set sock_set;
430
431 if (m_fd < 0)
432 return FALSE;
433 if (m_unrd_size > 0)
434 return TRUE;
435
436 tv.tv_sec = 0;
437 tv.tv_usec = 0;
438 FD_ZERO(&sock_set);
439 FD_SET(m_fd, &sock_set);
440 select(FD_SETSIZE, &sock_set, NULL, NULL, &tv);
441 return (FD_ISSET(m_fd, &sock_set) != 0);
442 }
443
444 // ---------------------------------------------------------------------
445 // --------- wxSocketBase Discard(): deletes all byte in the input queue
446 // ---------------------------------------------------------------------
447 void wxSocketBase::Discard()
448 {
449 #define MAX_BUFSIZE (10*1024)
450 char *my_data = new char[MAX_BUFSIZE];
451 size_t recv_size = MAX_BUFSIZE;
452
453 SaveState();
454 SetFlags((wxSockFlags)(NOWAIT | SPEED));
455
456 while (recv_size == MAX_BUFSIZE) {
457 recv_size = Read(my_data, MAX_BUFSIZE).LastCount();
458 }
459
460 RestoreState();
461 delete [] my_data;
462
463 #undef MAX_BUFSIZE
464 }
465
466 // --------------------------------------------------------------
467 // --------- wxSocketBase socket info functions -----------------
468 // --------------------------------------------------------------
469 bool wxSocketBase::GetPeer(wxSockAddress& addr_man) const
470 {
471 struct sockaddr my_addr;
472 size_t len_addr = sizeof(my_addr);
473
474 if (m_fd < 0)
475 return FALSE;
476
477 if (getpeername(m_fd, (struct sockaddr *)&my_addr, (int *)&len_addr) < 0)
478 return FALSE;
479
480 addr_man.Disassemble(&my_addr, len_addr);
481 return TRUE;
482 }
483
484 bool wxSocketBase::GetLocal(wxSockAddress& addr_man) const
485 {
486 struct sockaddr my_addr;
487 size_t len_addr = sizeof(my_addr);
488
489 if (m_fd < 0)
490 return FALSE;
491
492 if (getsockname(m_fd, (struct sockaddr *)&my_addr, (int *)&len_addr) < 0)
493 return FALSE;
494
495 addr_man.Disassemble(&my_addr, len_addr);
496 return TRUE;
497 }
498
499 // --------------------------------------------------------------
500 // --------- wxSocketBase wait functions ------------------------
501 // --------------------------------------------------------------
502 void wxSocketBase::SaveState()
503 {
504 wxSockState *state = new wxSockState;
505
506 state->cbk_on = m_cbkon;
507 state->cbk_set= m_neededreq;
508 state->cbk = m_cbk;
509 state->cdata = m_cdata;
510 state->flags = m_flags;
511 state->notif = m_notifyme;
512
513 m_states.Append(state);
514 }
515
516 void wxSocketBase::RestoreState()
517 {
518 wxNode *node;
519
520 node = m_states.Last();
521 if (!node)
522 return;
523
524 wxSockState *state = (wxSockState *)node->Data();
525
526 SetFlags(state->flags);
527 m_neededreq = state->cbk_set;
528 m_cbk = state->cbk;
529 m_cdata = state->cdata;
530 m_notifyme = state->notif;
531 if (state->cbk_on)
532 SetupCallbacks();
533 else
534 DestroyCallbacks();
535
536 delete node;
537 delete state;
538 }
539
540 // --------------------------------------------------------------
541 // --------- wxSocketBase wait functions ------------------------
542 // --------------------------------------------------------------
543 //
544 bool wxSocketBase::_Wait(long seconds, long microseconds, int type)
545 {
546 if ((!m_connected && !m_connecting) || m_fd < 0)
547 return FALSE;
548
549 wxSockWakeUp wakeup(this, &m_waitflags, 0);
550
551 SaveState();
552 SetNotify((wxRequestNotify)type);
553 SetupCallbacks();
554
555 if (seconds != -1)
556 wakeup.Start((int)(seconds*1000 + (microseconds / 1000)), TRUE);
557
558 m_waitflags = 0x80 | type;
559 while (m_waitflags & 0x80)
560 PROCESS_EVENTS();
561
562 RestoreState();
563
564 if (m_waitflags & 0x40) {
565 m_waitflags = 0;
566 return TRUE;
567 }
568 m_waitflags = 0;
569
570 return FALSE;
571 }
572
573 bool wxSocketBase::Wait(long seconds, long microseconds)
574 {
575 return _Wait(seconds, microseconds, REQ_ACCEPT | REQ_CONNECT |
576 REQ_READ | REQ_WRITE | REQ_LOST);
577 }
578
579 bool wxSocketBase::WaitForRead(long seconds, long microseconds)
580 {
581 return _Wait(seconds, microseconds, REQ_READ | REQ_LOST);
582 }
583
584 bool wxSocketBase::WaitForWrite(long seconds, long microseconds)
585 {
586 return _Wait(seconds, microseconds, REQ_WRITE);
587 }
588
589 bool wxSocketBase::WaitForLost(long seconds, long microseconds)
590 {
591 return _Wait(seconds, microseconds, REQ_LOST);
592 }
593
594 // --------------------------------------------------------------
595 // --------- wxSocketBase callback management -------------------
596 // --------------------------------------------------------------
597
598 #if defined(__WXMOTIF__) || defined(__WXXT__) || defined(__WXGTK__)
599 #if defined(__WXMOTIF__) || defined(__WXXT__)
600 static void wx_socket_read(XtPointer client, int *fid,
601 XtInputId *WXUNUSED(id))
602 #define fd *fid
603 #else
604 static void wx_socket_read(gpointer client, gint fd,
605 GdkInputCondition WXUNUSED(cond))
606 #define fd fd
607 #endif
608 {
609 wxSocketBase *sock = (wxSocketBase *)client;
610 char c;
611 int i;
612
613 i = recv(fd, &c, 1, MSG_PEEK);
614
615 if (i == -1 && (sock->NeededReq() & wxSocketBase::REQ_ACCEPT)) {
616 sock->OnRequest(wxSocketBase::EVT_ACCEPT);
617 return;
618 }
619
620 if (i != 0) {
621 if (!(sock->NeededReq() & wxSocketBase::REQ_READ))
622 return;
623
624 sock->OnRequest(wxSocketBase::EVT_READ);
625 } else {
626 if (!(sock->NeededReq() & wxSocketBase::REQ_LOST)) {
627 sock->Close();
628 return;
629 }
630
631 sock->OnRequest(wxSocketBase::EVT_LOST);
632 }
633 }
634 #undef fd
635
636 #if defined(__WXMOTIF__) || defined(__WXXT__)
637 static void wx_socket_write(XtPointer client, int *WXUNUSED(fid),
638 XtInputId *WXUNUSED(id))
639 #else
640 static void wx_socket_write(gpointer client, gint WXUNUSED(fd),
641 GdkInputCondition WXUNUSED(cond))
642 #endif
643 {
644 wxSocketBase *sock = (wxSocketBase *)client;
645
646 if (!sock->IsConnected())
647 sock->OnRequest(wxSocketBase::EVT_CONNECT);
648 else
649 sock->OnRequest(wxSocketBase::EVT_WRITE);
650 }
651 #endif
652
653 #ifdef wx_xview
654 Notify_value wx_sock_read_xview (Notify_client client, int fd)
655 {
656 wxSocketBase *sock = (wxSocketBase *)client;
657 char c;
658 int i;
659
660 i = recv(fd, &c, 1, MSG_PEEK);
661
662 if (i == -1 && (sock->NeededReq() & wxSocketBase::REQ_ACCEPT)) {
663 sock->OnRequest(wxSocketBase::EVT_ACCEPT);
664 return;
665 }
666
667 /* Bytes arrived */
668 if (i != 0) {
669 if (!(sock->NeededReq() & wxSocketBase::REQ_READ))
670 return (Notify_value) FALSE;
671
672 sock->OnRequest(wxSocketBase::EVT_READ);
673 } else {
674 if (!(sock->NeededReq() & wxSocketBase::REQ_LOST))
675 return;
676
677 sock->OnRequest(wxSocketBase::EVT_LOST);
678 }
679
680 return (Notify_value) FALSE;
681 }
682
683 Notify_value wx_sock_write_xview (Notify_client client, int fd)
684 {
685 wxSocketBase *sock = (wxSocketBase *)client;
686
687 if (!sock->IsConnected())
688 sock->OnRequest(wxSocketBase::EVT_CONNECT);
689 else
690 sock->OnRequest(wxSocketBase::EVT_WRITE);
691
692 return (Notify_value) TRUE;
693 }
694 #endif
695
696 wxSocketBase::wxRequestNotify wxSocketBase::EventToNotify(wxRequestEvent evt)
697 {
698 switch (evt) {
699 case EVT_READ:
700 return REQ_READ;
701 case EVT_PEEK:
702 return REQ_PEEK;
703 case EVT_WRITE:
704 return REQ_WRITE;
705 case EVT_LOST:
706 return REQ_LOST;
707 case EVT_ACCEPT:
708 return REQ_ACCEPT;
709 case EVT_CONNECT:
710 return REQ_CONNECT;
711 }
712 return 0;
713 }
714
715 void wxSocketBase::SetFlags(wxSockFlags _flags)
716 {
717 m_flags = _flags;
718 if (_flags & SPEED) {
719 unsigned long flag = 0;
720 ioctl(m_fd, FIONBIO, &flag);
721
722 // SPEED and WAITALL are antagonists.
723 m_flags = (wxSockFlags)(m_flags & ~WAITALL);
724
725 Notify(FALSE);
726 } else {
727 unsigned long flag = 1;
728 ioctl(m_fd, FIONBIO, &flag);
729 }
730 }
731
732 void wxSocketBase::SetNotify(wxRequestNotify flags)
733 {
734 wxRequestNotify old_needed_req = m_neededreq;
735 if (flags & REQ_ACCEPT) {
736 /* Check if server */
737 if (!(GetClassInfo()->IsKindOf(CLASSINFO(wxSocketServer))))
738 flags &= ~REQ_ACCEPT;
739 }
740 m_neededreq = flags;
741 if (m_cbkon && old_needed_req != flags)
742 SetupCallbacks();
743 }
744
745 void wxSocketBase::SetupCallbacks()
746 {
747 if (m_fd == INVALID_SOCKET || !m_handler || (m_flags & SPEED))
748 return;
749
750 #if defined(__WXMOTIF__) || defined(__WXXT__) || defined(__WXGTK__)
751 if (m_cbkon)
752 DestroyCallbacks();
753 if (m_neededreq & (REQ_ACCEPT | REQ_READ | REQ_LOST)) {
754 #ifdef __WXGTK__
755 m_internal->sock_inputid = gdk_input_add(m_fd, GDK_INPUT_READ,
756 wx_socket_read, (gpointer)this);
757 #else
758 m_internal->sock_inputid = XtAppAddInput (wxAPP_CONTEXT, m_fd,
759 (XtPointer *) XtInputReadMask,
760 (XtInputCallbackProc) wx_socket_read,
761 (XtPointer) this);
762 #endif
763 }
764 if (m_neededreq & (REQ_CONNECT | REQ_WRITE)) {
765 #ifdef __WXGTK__
766 m_internal->sock_inputid = gdk_input_add(m_fd, GDK_INPUT_WRITE,
767 wx_socket_write, (gpointer)this);
768 #else
769 m_internal->sock_outputid = XtAppAddInput (wxAPP_CONTEXT, m_fd,
770 (XtPointer *) XtInputWriteMask,
771 (XtInputCallbackProc) wx_socket_write,
772 (XtPointer) this);
773 #endif
774 }
775 #endif
776 #ifdef __WINDOWS__
777 WORD mask = 0;
778
779 if (m_neededreq & REQ_READ)
780 mask |= FD_READ;
781 if (m_neededreq & REQ_WRITE)
782 mask |= FD_WRITE;
783 if (m_neededreq & REQ_LOST)
784 mask |= FD_CLOSE;
785 if (m_neededreq & REQ_ACCEPT)
786 mask |= FD_ACCEPT;
787 if (m_neededreq & REQ_CONNECT)
788 mask |= FD_CONNECT;
789
790 if (!m_internal->my_msg)
791 m_internal->my_msg = m_handler->NewMessage(this);
792 WSAAsyncSelect(m_fd, m_handler->GetHWND(), m_internal->my_msg, mask);
793 #endif
794 m_cbkon = TRUE;
795 m_processing = FALSE;
796 }
797
798 void wxSocketBase::DestroyCallbacks()
799 {
800 if (!m_cbkon || !m_handler)
801 return;
802 m_cbkon = FALSE;
803 m_processing = FALSE;
804 #if defined(__WXMOTIF__) || defined(__WXXT__)
805 if (m_internal->sock_inputid > 0)
806 XtRemoveInput(m_internal->sock_inputid);
807 m_internal->sock_inputid = 0;
808 if (m_internal->sock_outputid > 0)
809 XtRemoveInput(m_internal->sock_outputid);
810 m_internal->sock_outputid = 0;
811 #endif
812 #ifdef __WXGTK__
813 if (m_internal->sock_inputid > 0)
814 gdk_input_remove(m_internal->sock_inputid);
815 m_internal->sock_inputid = 0;
816 if (m_internal->sock_outputid > 0)
817 gdk_input_remove(m_internal->sock_outputid);
818 m_internal->sock_outputid = 0;
819 #endif
820 #ifdef __WINDOWS__
821 WSAAsyncSelect(m_fd, m_handler->GetHWND(), 0, 0);
822 #endif
823 }
824
825 void wxSocketBase::Notify(bool notify)
826 {
827 if (m_notifyme == notify)
828 return;
829 if (notify)
830 SetupCallbacks();
831 else
832 DestroyCallbacks();
833 m_notifyme = notify;
834 }
835
836 void wxSocketBase::OnRequest(wxRequestEvent req_evt)
837 {
838 wxRequestNotify req_notif = EventToNotify(req_evt);
839
840 // Mask the current event
841 SetNotify(m_neededreq & ~req_notif);
842
843 if (req_evt <= EVT_WRITE && DoRequests(req_evt))
844 return;
845
846 if (m_waitflags & 0xF0) {
847 // Wake up
848 if ((m_waitflags & 0x0F) == req_evt) {
849 m_waitflags = 0x80;
850 #ifndef __WXGTK__
851 DestroyCallbacks(); // I disable it to prevent infinite loop on X11.
852 #endif
853 }
854 return;
855 }
856
857 if (req_evt == EVT_LOST) {
858 m_connected = FALSE;
859 Close();
860 }
861 if (m_notifyme)
862 OldOnNotify(req_evt);
863
864 // Unmask
865 SetNotify(m_neededreq | req_notif);
866 }
867
868 wxSocketEvent::wxSocketEvent(int id)
869 : wxEvent(id)
870 {
871 wxEventType type = (wxEventType)wxEVT_SOCKET;
872
873 SetEventType(type);
874 }
875
876 void wxSocketBase::OldOnNotify(wxRequestEvent evt)
877 {
878 wxSocketEvent event(m_id);
879
880 event.SetEventObject(this);
881 event.m_skevt = evt;
882 ProcessEvent(event);
883
884 if (m_cbk)
885 m_cbk(*this, evt, m_cdata);
886 }
887
888 // --------------------------------------------------------------
889 // --------- wxSocketBase functions [Callback, CallbackData] ----
890 // --------------------------------------------------------------
891 wxSocketBase::wxSockCbk wxSocketBase::Callback(wxSocketBase::wxSockCbk _cbk)
892 {
893 wxSockCbk old_cbk = m_cbk;
894
895 m_cbk = _cbk;
896 return old_cbk;
897 }
898
899 char *wxSocketBase::CallbackData(char *cdata_)
900 {
901 char *old_cdata = m_cdata;
902
903 m_cdata = cdata_;
904 return old_cdata;
905 }
906
907 void wxSocketBase::SetEventHandler(wxEvtHandler& h_evt, int id)
908 {
909 SetNextHandler(&h_evt);
910 m_id = id;
911 }
912
913 // --------------------------------------------------------------
914 // --------- wxSocketBase pushback library ----------------------
915 // --------------------------------------------------------------
916 void wxSocketBase::CreatePushbackAfter(const char *buffer, size_t size)
917 {
918 char *curr_pos;
919
920 m_unread = (char *) realloc(m_unread, m_unrd_size+size);
921 curr_pos = m_unread + m_unrd_size;
922
923 memcpy(curr_pos, buffer, size);
924 m_unrd_size += size;
925 }
926
927 void wxSocketBase::CreatePushbackBefore(const char *buffer, size_t size)
928 {
929 char *curr_pos, *new_buf;
930
931 new_buf = (char *) malloc(m_unrd_size+size);
932 curr_pos = new_buf + size;
933
934 memcpy(new_buf, buffer, size);
935 memcpy(curr_pos, m_unread, m_unrd_size);
936
937 free(m_unread);
938 m_unread = new_buf;
939 m_unrd_size += size;
940 }
941
942 size_t wxSocketBase::GetPushback(char *buffer, size_t size, bool peek)
943 {
944 if (!m_unrd_size)
945 return 0;
946
947 if (size > m_unrd_size)
948 size = m_unrd_size;
949 memcpy(buffer, m_unread, size);
950
951 if (!peek) {
952 m_unrd_size -= size;
953 if (!m_unrd_size) {
954 free(m_unread);
955 m_unread = NULL;
956 }
957 }
958
959 return size;
960 }
961
962 // --------------------------------------------------------------
963 // --------- wxSocketBase "multi-thread" core -------------------
964 // --------------------------------------------------------------
965
966 bool wxSocketBase::DoRequests(wxRequestEvent req_flag)
967 {
968 wxNode *node = req_list[req_flag].First();
969 size_t len;
970 int ret;
971
972 if (!node)
973 return FALSE;
974
975 SockRequest *req = (SockRequest *)node->Data();
976
977 delete node;
978
979 switch (req->type) {
980 case EVT_READ:
981 case EVT_PEEK:
982 ret = recv(m_fd, req->buffer, req->size,
983 (req->type == EVT_PEEK) ? MSG_PEEK : 0);
984 if (ret < 0) {
985 req->error = errno;
986 req->done = TRUE;
987 break;
988 }
989 len = ret;
990 if ((len < req->size) && (m_flags & WAITALL)) {
991 req->size -= len;
992 req->nbytes += len;
993 req->buffer += len;
994 req->auto_wakeup->Start(m_timeout*1000, TRUE);
995 req_list[req_flag].Insert(req);
996 break;
997 }
998 req->done = TRUE;
999 req->nbytes += len;
1000 #ifndef __WXGTK__
1001 DestroyCallbacks();
1002 #endif
1003 break;
1004 case EVT_WRITE:
1005 ret = send(m_fd, req->buffer, req->size, 0);
1006 if (ret < 0) {
1007 req->error = errno;
1008 req->done = TRUE;
1009 break;
1010 }
1011 len = ret;
1012 if ((len < req->size) && (m_flags & WAITALL)) {
1013 req->size -= len;
1014 req->nbytes += len;
1015 req->buffer += len;
1016 req->auto_wakeup->Start(m_timeout*1000, TRUE);
1017 req_list[req_flag].Insert(req);
1018 break;
1019 }
1020 req->done = TRUE;
1021 req->nbytes += len;
1022 #ifndef __WXGTK__
1023 DestroyCallbacks();
1024 #endif
1025 break;
1026 default:
1027 return FALSE;
1028 }
1029 return TRUE;
1030 }
1031
1032 void wxSocketBase::WantSpeedBuffer(char *buffer, size_t nbytes,
1033 wxRequestEvent evt)
1034 {
1035 int ret = 0;
1036
1037 switch (evt) {
1038 case EVT_PEEK:
1039 case EVT_READ:
1040 ret = recv(m_fd, buffer, nbytes,
1041 (evt == EVT_PEEK) ? MSG_PEEK : 0);
1042 break;
1043 case EVT_WRITE:
1044 ret = send(m_fd, buffer, nbytes, 0);
1045 break;
1046 }
1047 if (ret < 0) {
1048 m_lcount = 0;
1049 m_error = errno;
1050 } else {
1051 m_lcount = ret;
1052 m_error = 0;
1053 }
1054 }
1055
1056 void wxSocketBase::WantBuffer(char *buffer, size_t nbytes,
1057 wxRequestEvent evt)
1058 {
1059 bool buf_timed_out;
1060
1061 if (m_fd == INVALID_SOCKET || !m_handler || !m_connected)
1062 return;
1063
1064 if (m_flags & SPEED) {
1065 WantSpeedBuffer(buffer, nbytes, evt);
1066 return;
1067 }
1068
1069 SockRequest *buf = new SockRequest;
1070 wxSockWakeUp s_wake(NULL, (int *)&buf_timed_out, (int)TRUE);
1071
1072 m_wantbuf++;
1073 req_list[evt].Append(buf);
1074
1075 SaveState();
1076 SetNotify(REQ_LOST | EventToNotify(evt));
1077 SetupCallbacks();
1078 buf->buffer = buffer;
1079 buf->size = nbytes;
1080 buf->done = FALSE;
1081 buf->type = evt;
1082 buf->nbytes = 0;
1083 buf->auto_wakeup = &s_wake;
1084 buf->error = 0;
1085 buf_timed_out = FALSE;
1086
1087 s_wake.Start(m_timeout*1000, TRUE);
1088 if (m_flags & NOWAIT) {
1089 DoRequests(evt);
1090 } else {
1091 while (!buf->done && !buf_timed_out)
1092 PROCESS_EVENTS();
1093 }
1094 m_wantbuf--;
1095 m_lcount = buf->nbytes;
1096 if (buf_timed_out)
1097 m_error = ETIMEDOUT;
1098 else
1099 m_error = buf->error;
1100
1101 delete buf;
1102 RestoreState();
1103 }
1104
1105 // --------------------------------------------------------------
1106 // wxSocketServer ///////////////////////////////////////////////
1107 // --------------------------------------------------------------
1108
1109 // --------------------------------------------------------------
1110 // --------- wxSocketServer CONSTRUCTOR -------------------------
1111 // --------------------------------------------------------------
1112 wxSocketServer::wxSocketServer(wxSockAddress& addr_man,
1113 wxSockFlags flags) :
1114 wxSocketBase(flags, SOCK_SERVER)
1115 {
1116 m_fd = socket(addr_man.GetFamily(), SOCK_STREAM, 0);
1117
1118 if (m_fd == INVALID_SOCKET)
1119 return;
1120
1121 int flag = 1;
1122 setsockopt(m_fd, SOL_SOCKET, SO_REUSEADDR, (char*)&flag, sizeof(int));
1123
1124 struct sockaddr *myaddr;
1125 size_t len;
1126
1127 addr_man.Build(myaddr, len);
1128 if (bind(m_fd, myaddr, addr_man.SockAddrLen()) < 0)
1129 return;
1130
1131 if (listen(m_fd, 5) < 0) {
1132 m_fd = INVALID_SOCKET;
1133 return;
1134 }
1135 }
1136
1137 // --------------------------------------------------------------
1138 // --------- wxSocketServer Accept ------------------------------
1139 // --------------------------------------------------------------
1140 bool wxSocketServer::AcceptWith(wxSocketBase& sock)
1141 {
1142 int fd2;
1143
1144 if ((fd2 = accept(m_fd, 0, 0)) < 0)
1145 return FALSE;
1146
1147 struct linger linger;
1148 linger.l_onoff = 0;
1149 linger.l_linger = 1;
1150
1151 setsockopt(fd2, SOL_SOCKET, SO_LINGER, (char*)&linger, sizeof(linger));
1152
1153 int flag = 0;
1154 setsockopt(fd2, SOL_SOCKET, SO_KEEPALIVE, (char*)&flag, sizeof(int));
1155
1156 if (!(sock.m_flags & SPEED)) {
1157 unsigned long flag2 = 1;
1158 ioctl(fd2, FIONBIO, &flag2);
1159 }
1160
1161 sock.m_type = SOCK_INTERNAL;
1162 sock.m_fd = fd2;
1163 sock.m_connected = TRUE;
1164
1165 return TRUE;
1166 }
1167
1168 wxSocketBase *wxSocketServer::Accept()
1169 {
1170 wxSocketBase* sock = new wxSocketBase();
1171
1172 sock->SetFlags((wxSockFlags)m_flags);
1173
1174 if (!AcceptWith(*sock))
1175 return NULL;
1176
1177 if (m_handler)
1178 m_handler->Register(sock);
1179
1180 return sock;
1181 }
1182
1183 // --------------------------------------------------------------
1184 // --------- wxSocketServer callbacks ---------------------------
1185 // --------------------------------------------------------------
1186 void wxSocketServer::OnRequest(wxRequestEvent evt)
1187 {
1188 if (evt == EVT_ACCEPT) {
1189 OldOnNotify(EVT_ACCEPT);
1190 }
1191 }
1192
1193 // --------------------------------------------------------------
1194 // wxSocketClient ///////////////////////////////////////////////
1195 // --------------------------------------------------------------
1196
1197 // --------- wxSocketClient CONSTRUCTOR -------------------------
1198 // --------------------------------------------------------------
1199 wxSocketClient::wxSocketClient(wxSockFlags _flags) :
1200 wxSocketBase(_flags, SOCK_CLIENT)
1201 {
1202 }
1203
1204 // --------------------------------------------------------------
1205 // --------- wxSocketClient DESTRUCTOR --------------------------
1206 // --------------------------------------------------------------
1207 wxSocketClient::~wxSocketClient()
1208 {
1209 }
1210
1211 // --------------------------------------------------------------
1212 // --------- wxSocketClient Connect functions -------------------
1213 // --------------------------------------------------------------
1214 bool wxSocketClient::Connect(wxSockAddress& addr_man, bool WXUNUSED(wait) )
1215 {
1216 struct linger linger;
1217
1218 if (IsConnected())
1219 Close();
1220
1221 m_fd = socket(addr_man.GetFamily(), SOCK_STREAM, 0);
1222
1223 if (m_fd < 0)
1224 return FALSE;
1225
1226 m_connected = FALSE;
1227
1228 linger.l_onoff = 1;
1229 linger.l_linger = 5;
1230 setsockopt(m_fd, SOL_SOCKET, SO_LINGER, (char*)&linger, sizeof(linger));
1231
1232 // Stay in touch with the state of things...
1233
1234 unsigned long flag = 1;
1235 setsockopt(m_fd, SOL_SOCKET, SO_KEEPALIVE, (char*)&flag, sizeof(int));
1236
1237 // Disable the nagle algorithm, which delays sends till the
1238 // buffer is full (or a certain time period has passed?)...
1239
1240 #if defined(__WINDOWS__) || (defined(IPPROTO_TCP) && defined(TCP_NODELAY))
1241 flag = 1;
1242 setsockopt(m_fd, IPPROTO_TCP, TCP_NODELAY, (char*)&flag, sizeof(int));
1243 #endif
1244
1245 struct sockaddr *remote;
1246 size_t len;
1247
1248 addr_man.Build(remote, len);
1249
1250 if (connect(m_fd, remote, len) != 0)
1251 return FALSE;
1252
1253 if (!(m_flags & SPEED)) {
1254 flag = 1;
1255 ioctl(m_fd, FIONBIO, &flag);
1256 }
1257
1258 Notify(TRUE);
1259
1260 m_connected = TRUE;
1261 return TRUE;
1262 }
1263
1264 bool wxSocketClient::WaitOnConnect(long seconds, long microseconds)
1265 {
1266 int ret = _Wait(seconds, microseconds, REQ_CONNECT | REQ_LOST);
1267
1268 if (ret)
1269 m_connected = TRUE;
1270
1271 return m_connected;
1272 }
1273
1274 void wxSocketClient::OnRequest(wxRequestEvent evt)
1275 {
1276 if (evt == EVT_CONNECT) {
1277 if (m_connected) {
1278 SetNotify(m_neededreq & ~REQ_CONNECT);
1279 return;
1280 }
1281 m_waitflags = 0x40;
1282 m_connected = TRUE;
1283 OldOnNotify(EVT_CONNECT);
1284 DestroyCallbacks();
1285 return;
1286 }
1287 wxSocketBase::OnRequest(evt);
1288 }
1289
1290 /////////////////////////////////////////////////////////////////
1291 // wxSocketHandler ///////////////////////////////////////////////
1292 /////////////////////////////////////////////////////////////////
1293
1294 wxSocketHandler *wxSocketHandler::master = NULL;
1295 #if defined(__WINDOWS__)
1296 static int win_initialized = 0;
1297 #endif
1298
1299 // --------------------------------------------------------------
1300 // --------- wxSocketHandler CONSTRUCTOR ------------------------
1301 // --------------------------------------------------------------
1302 #ifdef __WINDOWS__
1303
1304 extern char wxPanelClassName[];
1305
1306 LRESULT APIENTRY _EXPORT wxSocketHandlerWndProc(HWND hWnd, UINT message,
1307 WPARAM wParam, LPARAM lParam)
1308 {
1309 if(message==WM_DESTROY)
1310 {
1311 ::SetWindowLong(hWnd, GWL_WNDPROC, (LONG) DefWindowProc);
1312 return DefWindowProc(hWnd, message, wParam, lParam);
1313 }
1314 wxSocketHandler *h_sock = (wxSocketHandler *)GetWindowLong(hWnd, GWL_USERDATA);
1315 wxNode *node = h_sock->smsg_list->Find(message);
1316 wxSocketBase *sock;
1317 wxSocketBase::wxRequestEvent sk_req;
1318 UINT event = WSAGETSELECTEVENT(lParam);
1319
1320 if (!node)
1321 return DefWindowProc(hWnd, message, wParam, lParam);
1322
1323 sock = (wxSocketBase *)node->Data();
1324
1325 switch (event) {
1326 case FD_READ:
1327 sk_req = wxSocketBase::EVT_READ;
1328 break;
1329 case FD_WRITE:
1330 sk_req = wxSocketBase::EVT_WRITE;
1331 break;
1332 case FD_CLOSE:
1333 sk_req = wxSocketBase::EVT_LOST;
1334 break;
1335 case FD_ACCEPT:
1336 sk_req = wxSocketBase::EVT_ACCEPT;
1337 break;
1338 case FD_CONNECT:
1339 sk_req = wxSocketBase::EVT_CONNECT;
1340 break;
1341 }
1342 sock->OnRequest(sk_req);
1343
1344 return (LRESULT)0;
1345 }
1346
1347 FARPROC wxSocketSubClassProc = NULL;
1348
1349 #endif
1350
1351 wxSocketHandler::wxSocketHandler()
1352 {
1353 #if defined(__WINDOWS__)
1354 if (!win_initialized) {
1355 WSADATA wsaData;
1356
1357 WSAStartup((1 << 8) | 1, &wsaData);
1358 win_initialized = 1;
1359 }
1360 internal = new wxSockHandlerInternal;
1361 internal->sockWin = ::CreateWindow(wxPanelClassName, NULL, 0,
1362 0, 0, 0, 0, NULL, (HMENU) NULL,
1363 wxhInstance, 0);
1364
1365 // Subclass the window
1366 if (!wxSocketSubClassProc)
1367 wxSocketSubClassProc = MakeProcInstance((FARPROC) wxSocketHandlerWndProc, wxhInstance);
1368 ::SetWindowLong(internal->sockWin, GWL_WNDPROC, (LONG) wxSocketSubClassProc);
1369 ::SetWindowLong(internal->sockWin, GWL_USERDATA, (LONG) this);
1370
1371 internal->firstAvailableMsg = 5000;
1372 smsg_list = new wxList(wxKEY_INTEGER);
1373 #endif
1374
1375 socks = new wxList;
1376
1377 #ifndef __WINDOWS__
1378 signal(SIGPIPE, SIG_IGN);
1379 #endif
1380 }
1381
1382 // --------------------------------------------------------------
1383 // --------- wxSocketHandler DESTRUCTOR -------------------------
1384 // --------------------------------------------------------------
1385 wxSocketHandler::~wxSocketHandler()
1386 {
1387 wxNode *next_node, *node = socks->First();
1388
1389 while (node) {
1390 wxSocketBase* sock = (wxSocketBase*)node->Data();
1391
1392 delete sock;
1393 next_node = node->Next();
1394 delete node;
1395 node = next_node;
1396 }
1397
1398 delete socks;
1399
1400 #ifdef __WINDOWS__
1401 delete smsg_list;
1402
1403 ::DestroyWindow(internal->sockWin);
1404 WSACleanup();
1405 win_initialized = 0;
1406
1407 delete internal;
1408 #endif
1409 }
1410
1411 // --------------------------------------------------------------
1412 // --------- wxSocketHandler registering functions --------------
1413 // --------------------------------------------------------------
1414 void wxSocketHandler::Register(wxSocketBase* sock)
1415 {
1416 wxNode *node;
1417
1418 for (node = socks->First(); node != NULL; node = node->Next()) {
1419 wxSocketBase* s = (wxSocketBase*)node->Data();
1420
1421 if (s == sock)
1422 return;
1423 }
1424
1425 if (sock) {
1426 socks->Append(sock);
1427 sock->SetHandler(this);
1428 sock->SetupCallbacks();
1429 }
1430 }
1431
1432 void wxSocketHandler::UnRegister(wxSocketBase* sock)
1433 {
1434 wxNode *node;
1435
1436 for (node = socks->First(); node; node = node->Next()) {
1437 wxSocketBase* s = (wxSocketBase*)node->Data();
1438
1439 if (s == sock) {
1440 delete node;
1441 sock->DestroyCallbacks();
1442 sock->SetHandler(NULL);
1443 return;
1444 }
1445 }
1446 }
1447
1448 unsigned long wxSocketHandler::Count() const
1449 {
1450 return socks->Number();
1451 }
1452
1453 // --------------------------------------------------------------
1454 // --------- wxSocketHandler "big" wait functions ---------------
1455 // --------------------------------------------------------------
1456 void handler_cbk(wxSocketBase& sock,
1457 wxSocketBase::wxRequestEvent WXUNUSED(flags),
1458 char *cdata)
1459 {
1460 int *a_wait = (int *)cdata;
1461
1462 (*a_wait)++;
1463 sock.Notify(FALSE);
1464 }
1465
1466 int wxSocketHandler::Wait(long seconds, long microseconds)
1467 {
1468 int i;
1469 int on_wait;
1470 wxSockWakeUp s_wake(NULL, &on_wait, -2);
1471 wxNode *node;
1472
1473 for (node = socks->First(), i=0; node; node = node->Next(), i++) {
1474 wxSocketBase *sock = (wxSocketBase *)node->Data();
1475
1476 sock->SaveState();
1477
1478 sock->SetupCallbacks();
1479
1480 sock->Callback(handler_cbk);
1481 sock->CallbackData((char *)&on_wait);
1482 }
1483 on_wait = 0;
1484 if (seconds != -1)
1485 s_wake.Start((seconds*1000) + (microseconds/1000), TRUE);
1486
1487 while (!on_wait)
1488 PROCESS_EVENTS();
1489
1490 for (node = socks->First(), i=0; node; node = node->Next(), i++) {
1491 wxSocketBase *sock = (wxSocketBase *)node->Data();
1492
1493 sock->RestoreState();
1494 }
1495
1496 if (on_wait == -2)
1497 return 0;
1498
1499 return on_wait;
1500 }
1501
1502 void wxSocketHandler::YieldSock()
1503 {
1504 wxNode *node;
1505
1506 for (node = socks->First(); node; node = node->Next() ) {
1507 wxSocketBase *sock = (wxSocketBase *)node->Data();
1508
1509 sock->SaveState();
1510
1511 sock->SetFlags(wxSocketBase::SPEED);
1512 if (sock->IsData())
1513 sock->DoRequests(wxSocketBase::EVT_READ);
1514 sock->DoRequests(wxSocketBase::EVT_WRITE);
1515
1516 sock->RestoreState();
1517 }
1518 }
1519
1520 // --------------------------------------------------------------
1521 // --------- wxSocketHandler: create and register the socket ----
1522 // --------------------------------------------------------------
1523 wxSocketServer *wxSocketHandler::CreateServer(wxSockAddress& addr,
1524 wxSocketBase::wxSockFlags flags)
1525 {
1526 wxSocketServer *serv = new wxSocketServer(addr, flags);
1527
1528 Register(serv);
1529 return serv;
1530 }
1531
1532 wxSocketClient *wxSocketHandler::CreateClient(wxSocketBase::wxSockFlags flags)
1533 {
1534 wxSocketClient *client = new wxSocketClient(flags);
1535
1536 Register(client);
1537 return client;
1538 }
1539
1540 #ifdef __WINDOWS__
1541 // --------------------------------------------------------------
1542 // --------- wxSocketHandler: Windows specific methods ----------
1543 // --------------------------------------------------------------
1544 UINT wxSocketHandler::NewMessage(wxSocketBase *sock)
1545 {
1546 internal->firstAvailableMsg++;
1547 smsg_list->Append(internal->firstAvailableMsg, sock);
1548 return internal->firstAvailableMsg;
1549 }
1550
1551 void wxSocketHandler::DestroyMessage(UINT msg)
1552 {
1553 wxNode *node = smsg_list->Find(msg);
1554 delete node;
1555 }
1556
1557 HWND wxSocketHandler::GetHWND() const
1558 {
1559 return internal->sockWin;
1560 }
1561
1562 #endif
1563
1564 bool wxSocketModule::OnInit() {
1565 wxSocketHandler::master = new wxSocketHandler();
1566 return TRUE;
1567 }
1568
1569 void wxSocketModule::OnExit() {
1570 delete wxSocketHandler::master;
1571 wxSocketHandler::master = NULL;
1572 }
1573
1574 #endif
1575 // __WXSTUBS__