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