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