Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(399)

Side by Side Diff: third_party/libjingle/files/talk/base/win32socketserver.cc

Issue 1110007: Removed win32socketserver and its use in mediator_thread_impl.cc. (Closed)
Patch Set: Created 10 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /*
2 * libjingle
3 * Copyright 2004--2005, Google Inc.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28 #include "talk/base/byteorder.h"
29 #include "talk/base/common.h"
30 #include "talk/base/logging.h"
31 #include "talk/base/winping.h"
32 #include "talk/base/winsock_initializer.h"
33 #include "talk/base/win32socketserver.h"
34 #include "talk/base/win32window.h"
35 #include <ws2tcpip.h>
36
37 namespace talk_base {
38
39 ///////////////////////////////////////////////////////////////////////////////
40 // Win32Socket
41 ///////////////////////////////////////////////////////////////////////////////
42
43 static const int kfRead = 0x0001;
44 static const int kfWrite = 0x0002;
45
46 // Standard MTUs
47 static const uint16 PACKET_MAXIMUMS[] = {
48 65535, // Theoretical maximum, Hyperchannel
49 32000, // Nothing
50 17914, // 16Mb IBM Token Ring
51 8166, // IEEE 802.4
52 //4464, // IEEE 802.5 (4Mb max)
53 4352, // FDDI
54 //2048, // Wideband Network
55 2002, // IEEE 802.5 (4Mb recommended)
56 //1536, // Expermental Ethernet Networks
57 //1500, // Ethernet, Point-to-Point (default)
58 1492, // IEEE 802.3
59 1006, // SLIP, ARPANET
60 //576, // X.25 Networks
61 //544, // DEC IP Portal
62 //512, // NETBIOS
63 508, // IEEE 802/Source-Rt Bridge, ARCNET
64 296, // Point-to-Point (low delay)
65 68, // Official minimum
66 0, // End of list marker
67 };
68
69 static const uint32 IP_HEADER_SIZE = 20;
70 static const uint32 ICMP_HEADER_SIZE = 8;
71
72 #ifdef DEBUG
73 LPCSTR WSAErrorToString(int error, LPCSTR *description_result) {
74 LPCSTR string = "Unspecified";
75 LPCSTR description = "Unspecified description";
76 switch (error) {
77 case ERROR_SUCCESS:
78 string = "SUCCESS";
79 description = "Operation succeeded";
80 break;
81 case WSAEWOULDBLOCK:
82 string = "WSAEWOULDBLOCK";
83 description = "Using a non-blocking socket, will notify later";
84 break;
85 case WSAEACCES:
86 string = "WSAEACCES";
87 description = "Access denied, or sharing violation";
88 break;
89 case WSAEADDRNOTAVAIL:
90 string = "WSAEADDRNOTAVAIL";
91 description = "Address is not valid in this context";
92 break;
93 case WSAENETDOWN:
94 string = "WSAENETDOWN";
95 description = "Network is down";
96 break;
97 case WSAENETUNREACH:
98 string = "WSAENETUNREACH";
99 description = "Network is up, but unreachable";
100 break;
101 case WSAENETRESET:
102 string = "WSANETRESET";
103 description = "Connection has been reset due to keep-alive activity";
104 break;
105 case WSAECONNABORTED:
106 string = "WSAECONNABORTED";
107 description = "Aborted by host";
108 break;
109 case WSAECONNRESET:
110 string = "WSAECONNRESET";
111 description = "Connection reset by host";
112 break;
113 case WSAETIMEDOUT:
114 string = "WSAETIMEDOUT";
115 description = "Timed out, host failed to respond";
116 break;
117 case WSAECONNREFUSED:
118 string = "WSAECONNREFUSED";
119 description = "Host actively refused connection";
120 break;
121 case WSAEHOSTDOWN:
122 string = "WSAEHOSTDOWN";
123 description = "Host is down";
124 break;
125 case WSAEHOSTUNREACH:
126 string = "WSAEHOSTUNREACH";
127 description = "Host is unreachable";
128 break;
129 case WSAHOST_NOT_FOUND:
130 string = "WSAHOST_NOT_FOUND";
131 description = "No such host is known";
132 break;
133 }
134 if (description_result) {
135 *description_result = description;
136 }
137 return string;
138 }
139
140 void ReportWSAError(LPCSTR context, int error, const sockaddr_in& addr) {
141 talk_base::SocketAddress address;
142 address.FromSockAddr(addr);
143 LPCSTR description_string;
144 LPCSTR error_string = WSAErrorToString(error, &description_string);
145 LOG(LS_INFO) << context << " = " << error
146 << " (" << error_string << ":" << description_string << ") ["
147 << address.ToString() << "]";
148 }
149 #else
150 void ReportWSAError(LPCSTR context, int error, const sockaddr_in& addr) { }
151 #endif
152
153 /////////////////////////////////////////////////////////////////////////////
154 // Win32Socket::EventSink
155 /////////////////////////////////////////////////////////////////////////////
156
157 #define WM_SOCKETNOTIFY (WM_USER + 50)
158 #define WM_DNSNOTIFY (WM_USER + 51)
159
160 struct Win32Socket::DnsLookup {
161 HANDLE handle;
162 uint16 port;
163 char buffer[MAXGETHOSTSTRUCT];
164 };
165
166 class Win32Socket::EventSink : public Win32Window {
167 public:
168 EventSink(Win32Socket * parent) : parent_(parent) { }
169
170 void Dispose();
171
172 virtual bool OnMessage(UINT uMsg, WPARAM wParam, LPARAM lParam,
173 LRESULT& result);
174 virtual void OnFinalMessage(HWND hWnd);
175
176 private:
177 bool OnSocketNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& result);
178 bool OnDnsNotify(WPARAM wParam, LPARAM lParam, LRESULT& result);
179
180 Win32Socket * parent_;
181 };
182
183 void
184 Win32Socket::EventSink::Dispose() {
185 parent_ = NULL;
186 if (::IsWindow(handle())) {
187 ::DestroyWindow(handle());
188 } else {
189 delete this;
190 }
191 }
192
193 bool Win32Socket::EventSink::OnMessage(UINT uMsg, WPARAM wParam, LPARAM lParam,
194 LRESULT& result) {
195 switch (uMsg) {
196 case WM_SOCKETNOTIFY:
197 case WM_TIMER:
198 return OnSocketNotify(uMsg, wParam, lParam, result);
199 case WM_DNSNOTIFY:
200 return OnDnsNotify(wParam, lParam, result);
201 }
202 return false;
203 }
204
205 bool
206 Win32Socket::EventSink::OnSocketNotify(UINT uMsg, WPARAM wParam, LPARAM lParam,
207 LRESULT& result) {
208 result = 0;
209
210 // Make sure the socket isn't already closed
211 if (!parent_ || (parent_->socket_ == INVALID_SOCKET))
212 return true;
213
214 int event = WSAGETSELECTEVENT(lParam);
215 int wsa_error = WSAGETSELECTERROR(lParam);
216
217 if (uMsg == WM_TIMER) {
218 event = FD_CLOSE;
219 wsa_error = WSAETIMEDOUT;
220 } else if (event == FD_CLOSE) {
221 char ch;
222 if (::recv(parent_->socket_, &ch, 1, MSG_PEEK) > 0) {
223 parent_->signal_close_ = true;
224 return true;
225 }
226 }
227
228 parent_->OnSocketNotify(event, wsa_error);
229 return true;
230 }
231
232 bool
233 Win32Socket::EventSink::OnDnsNotify(WPARAM wParam, LPARAM lParam,
234 LRESULT& result) {
235 result = 0;
236
237 if (!parent_)
238 return true;
239
240 if (!parent_->dns_ ||
241 (parent_->dns_->handle != reinterpret_cast<HANDLE>(wParam))) {
242 ASSERT(false);
243 return true;
244 }
245
246 uint32 ip = 0;
247 int error = WSAGETASYNCERROR(lParam);
248
249 if (error == 0) {
250 hostent * pHost = reinterpret_cast<hostent *>(parent_->dns_->buffer);
251 uint32 net_ip = *reinterpret_cast<uint32 *>(pHost->h_addr_list[0]);
252 ip = talk_base::NetworkToHost32(net_ip);
253 }
254
255 parent_->OnDnsNotify(ip, error);
256 return true;
257 }
258
259 void
260 Win32Socket::EventSink::OnFinalMessage(HWND hWnd) {
261 delete this;
262 }
263
264 /////////////////////////////////////////////////////////////////////////////
265 // Win32Socket
266 /////////////////////////////////////////////////////////////////////////////
267
268 Win32Socket::Win32Socket()
269 : socket_(INVALID_SOCKET), error_(0), state_(CS_CLOSED),
270 signal_close_(false), sink_(NULL), dns_(NULL) {
271 talk_base::EnsureWinsockInit();
272 // TODO: replace addr_ with SocketAddress
273 memset(&addr_, 0, sizeof(addr_));
274 }
275
276 Win32Socket::~Win32Socket() {
277 Close();
278 }
279
280 int
281 Win32Socket::Attach(SOCKET s) {
282 ASSERT(socket_ == INVALID_SOCKET);
283 if (socket_ != INVALID_SOCKET)
284 return SOCKET_ERROR;
285
286 ASSERT(s != INVALID_SOCKET);
287 if (s == INVALID_SOCKET)
288 return SOCKET_ERROR;
289
290 socket_ = s;
291 state_ = CS_CONNECTED;
292
293 if (!Create(FD_READ | FD_WRITE | FD_CLOSE))
294 return SOCKET_ERROR;
295
296 return 0;
297 }
298
299 void
300 Win32Socket::SetTimeout(int ms) {
301 if (sink_)
302 ::SetTimer(sink_->handle(), 1, ms, 0);
303 }
304
305 talk_base::SocketAddress
306 Win32Socket::GetLocalAddress() const {
307 sockaddr_in addr;
308 socklen_t addrlen = sizeof(addr);
309 int result = ::getsockname(socket_, (sockaddr*)&addr, &addrlen);
310 ASSERT(addrlen == sizeof(addr));
311 talk_base::SocketAddress address;
312 if (result >= 0) {
313 address.FromSockAddr(addr);
314 } else {
315 ASSERT(result >= 0);
316 }
317 return address;
318 }
319
320 talk_base::SocketAddress
321 Win32Socket::GetRemoteAddress() const {
322 sockaddr_in addr;
323 socklen_t addrlen = sizeof(addr);
324 int result = ::getpeername(socket_, (sockaddr*)&addr, &addrlen);
325 ASSERT(addrlen == sizeof(addr));
326 talk_base::SocketAddress address;
327 if (result >= 0) {
328 address.FromSockAddr(addr);
329 } else {
330 ASSERT(errno == ENOTCONN);
331 }
332 return address;
333 }
334
335 int
336 Win32Socket::Bind(const talk_base::SocketAddress& addr) {
337 ASSERT(socket_ == INVALID_SOCKET);
338 if (socket_ != INVALID_SOCKET)
339 return SOCKET_ERROR;
340
341 if (!Create(FD_ACCEPT | FD_CLOSE))
342 return SOCKET_ERROR;
343
344 sockaddr_in saddr;
345 addr.ToSockAddr(&saddr);
346 int err = ::bind(socket_, (sockaddr*)&saddr, sizeof(saddr));
347 UpdateLastError();
348 return err;
349 }
350
351 int
352 Win32Socket::Connect(const talk_base::SocketAddress& addr) {
353 ASSERT(socket_ == INVALID_SOCKET);
354 if (socket_ != INVALID_SOCKET)
355 return SOCKET_ERROR;
356
357 if (!Create(FD_READ | FD_WRITE | FD_CONNECT | FD_CLOSE))
358 return SOCKET_ERROR;
359
360 if (!addr.IsUnresolved()) {
361 sockaddr_in saddr;
362 addr.ToSockAddr(&saddr);
363
364 // now connect
365 return DoConnect(saddr);
366 }
367
368 LOG_F(LS_INFO) << "async dns lookup (" << addr.IPAsString() << ")";
369 DnsLookup * dns = new DnsLookup;
370 dns->handle = WSAAsyncGetHostByName(sink_->handle(), WM_DNSNOTIFY,
371 addr.IPAsString().c_str(), dns->buffer, sizeof(dns->buffer));
372
373 if (!dns->handle) {
374 LOG_F(LS_ERROR) << "WSAAsyncGetHostByName error: " << WSAGetLastError();
375 delete dns;
376 UpdateLastError();
377 Close();
378 return SOCKET_ERROR;
379 }
380
381 dns->port = addr.port();
382 dns_ = dns;
383 state_ = CS_CONNECTING;
384 return 0;
385 }
386
387 int
388 Win32Socket::DoConnect(const sockaddr_in& addr) {
389 connect_time_ = talk_base::GetMillisecondCount();
390 int result = connect(socket_, (SOCKADDR*)&addr, sizeof(addr));
391 if (result == SOCKET_ERROR) {
392 int code = WSAGetLastError();
393 if (code != WSAEWOULDBLOCK) {
394 ReportWSAError("WSAAsync:connect", code, addr);
395 error_ = code;
396 Close();
397 return SOCKET_ERROR;
398 }
399 }
400 addr_ = addr;
401 state_ = CS_CONNECTING;
402 return 0;
403 }
404
405 void
406 Win32Socket::OnSocketNotify(int event, int error) {
407 error_ = error;
408 switch (event) {
409 case FD_CONNECT:
410 if (error != ERROR_SUCCESS) {
411 ReportWSAError("WSAAsync:connect notify", error, addr_);
412 #ifdef DEBUG
413 int32 duration = talk_base::TimeDiff(talk_base::GetMillisecondCount(),
414 connect_time_);
415 LOG(LS_INFO) << "WSAAsync:connect error (" << duration
416 << " ms), faking close";
417 #endif
418 Close();
419 // If you get an error connecting, close doesn't really do anything
420 // and it certainly doesn't send back any close notification, but
421 // we really only maintain a few states, so it is easiest to get
422 // back into a known state by pretending that a close happened, even
423 // though the connect event never did occur.
424 SignalCloseEvent(this, error);
425 } else {
426 #ifdef DEBUG
427 int32 duration = talk_base::TimeDiff(talk_base::GetMillisecondCount(),
428 connect_time_);
429 LOG(LS_INFO) << "WSAAsync:connect (" << duration << " ms)";
430 #endif
431 state_ = CS_CONNECTED;
432 SignalConnectEvent(this);
433 }
434 break;
435
436 case FD_ACCEPT:
437 case FD_READ:
438 if (error != ERROR_SUCCESS) {
439 ReportWSAError("WSAAsync:read notify", error, addr_);
440 Close();
441 } else {
442 SignalReadEvent(this);
443 }
444 break;
445
446 case FD_WRITE:
447 if (error != ERROR_SUCCESS) {
448 ReportWSAError("WSAAsync:write notify", error, addr_);
449 Close();
450 } else {
451 SignalWriteEvent(this);
452 }
453 break;
454
455 case FD_CLOSE:
456 ReportWSAError("WSAAsync:close notify", error, addr_);
457 Close();
458 SignalCloseEvent(this, error);
459 break;
460 }
461 }
462
463 void
464 Win32Socket::OnDnsNotify(int ip, int error) {
465 LOG_F(LS_INFO) << "(" << talk_base::SocketAddress::IPToString(ip)
466 << ", " << error << ")";
467 if (error == 0) {
468 talk_base::SocketAddress address(ip, dns_->port);
469 sockaddr_in addr;
470 address.ToSockAddr(&addr);
471 error = DoConnect(addr);
472 } else {
473 Close();
474 }
475
476 if (error) {
477 error_ = error;
478 SignalCloseEvent(this, error_);
479 } else {
480 delete dns_;
481 dns_ = NULL;
482 }
483 }
484
485 int
486 Win32Socket::GetError() const {
487 return error_;
488 }
489
490 void
491 Win32Socket::SetError(int error) {
492 error_ = error;
493 }
494
495 Socket::ConnState
496 Win32Socket::GetState() const {
497 return state_;
498 }
499
500 int
501 Win32Socket::SetOption(Option opt, int value) {
502 ASSERT(opt == OPT_DONTFRAGMENT);
503 value = (value == 0) ? 0 : 1;
504 return ::setsockopt(socket_, IPPROTO_IP, IP_DONTFRAGMENT,
505 reinterpret_cast<char*>(&value), sizeof(value));
506 }
507
508 int
509 Win32Socket::Send(const void *pv, size_t cb) {
510 int sent = ::send(socket_, reinterpret_cast<const char *>(pv), (int)cb, 0);
511 UpdateLastError();
512 return sent;
513 }
514
515 int
516 Win32Socket::SendTo(const void *pv, size_t cb,
517 const talk_base::SocketAddress& addr) {
518 sockaddr_in saddr;
519 addr.ToSockAddr(&saddr);
520 int sent = ::sendto(socket_, reinterpret_cast<const char *>(pv), (int)cb, 0,
521 (sockaddr*)&saddr, sizeof(saddr));
522 UpdateLastError();
523 return sent;
524 }
525
526 int
527 Win32Socket::Recv(void *pv, size_t cb) {
528 int received = ::recv(socket_, (char *)pv, (int)cb, 0);
529 UpdateLastError();
530 if (signal_close_ && (received > 0)) {
531 char ch;
532 if (::recv(socket_, &ch, 1, MSG_PEEK) <= 0) {
533 signal_close_ = false;
534 ::PostMessage(sink_->handle(), WM_SOCKETNOTIFY,
535 WSAMAKESELECTREPLY(FD_CLOSE, 0), 0);
536 }
537 }
538 return received;
539 }
540
541 int
542 Win32Socket::RecvFrom(void *pv, size_t cb, talk_base::SocketAddress *paddr) {
543 sockaddr_in saddr;
544 socklen_t cbAddr = sizeof(saddr);
545 int received = ::recvfrom(socket_, (char *)pv, (int)cb, 0, (sockaddr*)&saddr,
546 &cbAddr);
547 UpdateLastError();
548 if (received != SOCKET_ERROR)
549 paddr->FromSockAddr(saddr);
550 if (signal_close_ && (received > 0)) {
551 char ch;
552 if (::recv(socket_, &ch, 1, MSG_PEEK) <= 0) {
553 signal_close_ = false;
554 ::PostMessage(sink_->handle(), WM_SOCKETNOTIFY,
555 WSAMAKESELECTREPLY(FD_CLOSE, 0), 0);
556 }
557 }
558 return received;
559 }
560
561 int
562 Win32Socket::Listen(int backlog) {
563 int err = ::listen(socket_, backlog);
564 UpdateLastError();
565 if (err == 0)
566 state_ = CS_CONNECTING;
567 return err;
568 }
569
570 talk_base::Socket*
571 Win32Socket::Accept(talk_base::SocketAddress *paddr) {
572 sockaddr_in saddr;
573 socklen_t cbAddr = sizeof(saddr);
574 SOCKET s = ::accept(socket_, (sockaddr*)&saddr, &cbAddr);
575 UpdateLastError();
576 if (s == INVALID_SOCKET)
577 return NULL;
578 if (paddr)
579 paddr->FromSockAddr(saddr);
580 Win32Socket* socket = new Win32Socket;
581 if (0 == socket->Attach(s))
582 return socket;
583 delete socket;
584 return NULL;
585 }
586
587 int
588 Win32Socket::Close() {
589 int err = 0;
590 if (socket_ != INVALID_SOCKET) {
591 err = ::closesocket(socket_);
592 socket_ = INVALID_SOCKET;
593 signal_close_ = false;
594 UpdateLastError();
595 }
596 if (dns_) {
597 WSACancelAsyncRequest(dns_->handle);
598 delete dns_;
599 dns_ = NULL;
600 }
601 if (sink_) {
602 sink_->Dispose();
603 sink_ = NULL;
604 }
605 memset(&addr_, 0, sizeof(addr_)); // no longer connected, zero ip/port
606 state_ = CS_CLOSED;
607 return err;
608 }
609
610 int
611 Win32Socket::EstimateMTU(uint16* mtu) {
612 talk_base::SocketAddress addr = GetRemoteAddress();
613 if (addr.IsAny()) {
614 error_ = ENOTCONN;
615 return -1;
616 }
617
618 talk_base::WinPing ping;
619 if (!ping.IsValid()) {
620 error_ = EINVAL; // can't think of a better error ID
621 return -1;
622 }
623
624 for (int level = 0; PACKET_MAXIMUMS[level + 1] > 0; ++level) {
625 int32 size = PACKET_MAXIMUMS[level] - IP_HEADER_SIZE - ICMP_HEADER_SIZE;
626 talk_base::WinPing::PingResult result =
627 ping.Ping(addr.ip(), size, 0, 1, false);
628 if (result == talk_base::WinPing::PING_FAIL) {
629 error_ = EINVAL; // can't think of a better error ID
630 return -1;
631 }
632 if (result != talk_base::WinPing::PING_TOO_LARGE) {
633 *mtu = PACKET_MAXIMUMS[level];
634 return 0;
635 }
636 }
637
638 ASSERT(false);
639 return 0;
640 }
641
642 bool
643 Win32Socket::Create(long events) {
644 ASSERT(NULL == sink_);
645
646 if (INVALID_SOCKET == socket_) {
647 socket_ = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, NULL, 0);
648 if (socket_ == INVALID_SOCKET) {
649 UpdateLastError();
650 return false;
651 }
652 }
653
654 // Create window
655 sink_ = new EventSink(this);
656 sink_->Create(NULL, L"EventSink", 0, 0, 0, 0, 10, 10);
657
658 // start the async select
659 if (WSAAsyncSelect(socket_, sink_->handle(), WM_SOCKETNOTIFY, events)
660 == SOCKET_ERROR) {
661 UpdateLastError();
662 Close();
663 return false;
664 }
665
666 return true;
667 }
668
669 void
670 Win32Socket::UpdateLastError() {
671 error_ = WSAGetLastError();
672 }
673
674 ///////////////////////////////////////////////////////////////////////////////
675 // Win32SocketServer
676 ///////////////////////////////////////////////////////////////////////////////
677
678 static UINT s_wm_wakeup_id;
679
680 LRESULT CALLBACK DummyWndProc(HWND hwnd, UINT wm, WPARAM wp, LPARAM lp);
681
682 // A socket server that provides cricket base services on top of a win32 gui thr ead
683
684 Win32SocketServer::Win32SocketServer(MessageQueue *message_queue) {
685 if (s_wm_wakeup_id == 0)
686 s_wm_wakeup_id = RegisterWindowMessage(L"WM_WAKEUP");
687 message_queue_ = message_queue;
688 hwnd_ = NULL;
689 CreateDummyWindow();
690 }
691
692 Win32SocketServer::~Win32SocketServer() {
693 if (hwnd_ != NULL) {
694 KillTimer(hwnd_, 1);
695 ::DestroyWindow(hwnd_);
696 }
697 }
698
699 Socket* Win32SocketServer::CreateSocket(int type) {
700 ASSERT(SOCK_STREAM == type);
701 return new Win32Socket;
702 }
703
704 AsyncSocket* Win32SocketServer::CreateAsyncSocket(int type) {
705 ASSERT(SOCK_STREAM == type);
706 return new Win32Socket;
707 }
708
709 bool Win32SocketServer::Wait(int cms, bool process_io) {
710 ASSERT(!process_io || (cms == 0)); // Should only be used for Thread::Send, o r in Pump, below
711 if (cms == -1) {
712 MSG msg;
713 GetMessage(&msg, NULL, s_wm_wakeup_id, s_wm_wakeup_id);
714 } else if (cms != 0) {
715 Sleep(cms);
716 }
717 return true;
718 }
719
720 void Win32SocketServer::WakeUp() {
721 // Always post for every wakeup, so there are no
722 // critical sections
723 if (hwnd_ != NULL)
724 PostMessage(hwnd_, s_wm_wakeup_id, 0, 0);
725 }
726
727 void Win32SocketServer::Pump() {
728 // Process messages
729 Message msg;
730 while (message_queue_->Get(&msg, 0))
731 message_queue_->Dispatch(&msg);
732
733 // Anything remaining?
734 int delay = message_queue_->GetDelay();
735 if (delay == -1) {
736 KillTimer(hwnd_, 1);
737 } else {
738 SetTimer(hwnd_, 1, delay, NULL);
739 }
740 }
741
742 void Win32SocketServer::CreateDummyWindow()
743 {
744 static bool s_registered;
745 if (!s_registered) {
746 ::WNDCLASSW wc;
747 memset(&wc, 0, sizeof(wc));
748 wc.cbWndExtra = sizeof(this);
749 wc.lpszClassName = L"Dummy";
750 wc.lpfnWndProc = DummyWndProc;
751 ::RegisterClassW(&wc);
752 s_registered = true;
753 }
754
755 hwnd_ = ::CreateWindowW(L"Dummy", L"", 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL);
756 SetWindowLong(hwnd_, GWL_USERDATA, (LONG)(LONG_PTR)this);
757 }
758
759 LRESULT CALLBACK DummyWndProc(HWND hwnd, UINT wm, WPARAM wp, LPARAM lp)
760 {
761 if (wm == s_wm_wakeup_id || (wm == WM_TIMER && wp == 1)) {
762 Win32SocketServer *ss = (Win32SocketServer *)(LONG_PTR)GetWindowLong(hwnd, G WL_USERDATA);
763 ss->Pump();
764 return 0;
765 }
766 return ::DefWindowProc(hwnd, wm, wp, lp);
767 }
768
769 } // namespace talk_base
OLDNEW
« no previous file with comments | « third_party/libjingle/files/talk/base/win32socketserver.h ('k') | third_party/libjingle/libjingle.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698