]> git.saurik.com Git - wxWidgets.git/blob - src/common/gsocketiohandler.cpp
shutdown sockets gracefully instead of doing it with TCP reset (patch 1682438)
[wxWidgets.git] / src / common / gsocketiohandler.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/gsocketiohandler.cpp
3 // Purpose: implementation of wxFDIOHandler for GSocket
4 // Author: Angel Vidal, Lukasz Michalski
5 // Modified by:
6 // Created: 08.24.06
7 // RCS-ID: $Id$
8 // Copyright: (c) 2006 Angel vidal
9 // License: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 // for compilers that support precompilation, includes "wx.h".
21 #include "wx/wxprec.h"
22
23 #if wxUSE_SOCKETS
24
25 #include "wx/private/gsocketiohandler.h"
26 #include "wx/unix/private.h"
27 #include "wx/gsocket.h"
28 #include "wx/unix/gsockunx.h"
29
30 // ============================================================================
31 // implementation
32 // ============================================================================
33
34 // ----------------------------------------------------------------------------
35 // wxGSocketIOHandler
36 // ----------------------------------------------------------------------------
37
38 wxGSocketIOHandler::wxGSocketIOHandler(GSocket* socket)
39 : m_socket(socket),
40 m_flags(0)
41 {
42
43 };
44
45 void wxGSocketIOHandler::OnReadWaiting(int fd)
46 {
47 m_socket->Detected_Read();
48 };
49
50 void wxGSocketIOHandler::OnWriteWaiting(int fd)
51 {
52 m_socket->Detected_Write();
53 };
54
55 void wxGSocketIOHandler::OnExceptionWaiting(int fd)
56 {
57 m_socket->Detected_Read();
58 };
59
60 int wxGSocketIOHandler::GetFlags() const
61 {
62 return m_flags;
63 };
64
65
66 void wxGSocketIOHandler::RemoveFlag(wxSelectDispatcherEntryFlags flag)
67 {
68 m_flags &= ~flag;
69 };
70
71 void wxGSocketIOHandler::AddFlag(wxSelectDispatcherEntryFlags flag)
72 {
73 m_flags |= flag;
74 };
75
76 // ----------------------------------------------------------------------------
77 // GSocket interface
78 // ----------------------------------------------------------------------------
79
80 bool GSocketGUIFunctionsTableConcrete::CanUseEventLoop()
81 {
82 return true;
83 }
84
85 bool GSocketGUIFunctionsTableConcrete::OnInit()
86 {
87 return true;
88 }
89
90 void GSocketGUIFunctionsTableConcrete::OnExit()
91 {
92 }
93
94 bool GSocketGUIFunctionsTableConcrete::Init_Socket(GSocket *socket)
95 {
96 int *m_id;
97
98 socket->m_gui_dependent = (char *)malloc(sizeof(int)*2);
99 m_id = (int *)(socket->m_gui_dependent);
100
101 m_id[0] = -1;
102 m_id[1] = -1;
103
104 return true;
105 }
106
107 void GSocketGUIFunctionsTableConcrete::Destroy_Socket(GSocket *socket)
108 {
109 free(socket->m_gui_dependent);
110 }
111
112 void GSocketGUIFunctionsTableConcrete::Install_Callback(GSocket *socket,
113 GSocketEvent event)
114 {
115 int *m_id = (int *)(socket->m_gui_dependent);
116 int c;
117
118 if (socket->m_fd == -1)
119 return;
120
121 switch (event)
122 {
123 case GSOCK_LOST: /* fall-through */
124 case GSOCK_INPUT: c = 0; break;
125 case GSOCK_OUTPUT: c = 1; break;
126 case GSOCK_CONNECTION: c = ((socket->m_server) ? 0 : 1); break;
127 default: return;
128 }
129
130 wxGSocketIOHandler* handler = (wxGSocketIOHandler*)(wxSelectDispatcher::Get().FindHandler(socket->m_fd));
131 if (handler == NULL)
132 {
133 handler = new wxGSocketIOHandler(socket);
134 };
135
136 if (c == 0)
137 {
138 m_id[0] = socket->m_fd;
139 handler->AddFlag(wxSelectInput);
140 }
141 else
142 {
143 m_id[1] = socket->m_fd;
144 handler->AddFlag(wxSelectOutput);
145 }
146
147 wxSelectDispatcher::Get().RegisterFD(socket->m_fd,handler,handler->GetFlags());
148 }
149
150 void GSocketGUIFunctionsTableConcrete::Uninstall_Callback(GSocket *socket,
151 GSocketEvent event)
152 {
153 int *m_id = (int *)(socket->m_gui_dependent);
154 int c;
155
156 switch (event)
157 {
158 case GSOCK_LOST: /* fall-through */
159 case GSOCK_INPUT: c = 0; break;
160 case GSOCK_OUTPUT: c = 1; break;
161 case GSOCK_CONNECTION: c = ((socket->m_server) ? 0 : 1); break;
162 default: return;
163 }
164
165 wxGSocketIOHandler* handler = NULL;
166 if ( m_id[c] != -1 )
167 {
168 if ( c == 0 )
169 {
170 handler = (wxGSocketIOHandler*)wxSelectDispatcher::Get().UnregisterFD(m_id[c], wxSelectInput);
171 if (handler != NULL)
172 handler->RemoveFlag(wxSelectInput);
173 }
174 else
175 {
176 handler = (wxGSocketIOHandler*)wxSelectDispatcher::Get().UnregisterFD(m_id[c], wxSelectOutput);
177 if (handler != NULL)
178 handler->RemoveFlag(wxSelectOutput);
179 }
180 if (handler && handler->GetFlags() == 0)
181 delete handler;
182 }
183
184 m_id[c] = -1;
185 }
186
187 void GSocketGUIFunctionsTableConcrete::Enable_Events(GSocket *socket)
188 {
189 Install_Callback(socket, GSOCK_INPUT);
190 Install_Callback(socket, GSOCK_OUTPUT);
191 }
192
193 void GSocketGUIFunctionsTableConcrete::Disable_Events(GSocket *socket)
194 {
195 Uninstall_Callback(socket, GSOCK_INPUT);
196 Uninstall_Callback(socket, GSOCK_OUTPUT);
197 }
198
199 #endif // wxUSE_SOCKETS