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

Side by Side Diff: base/sync_socket_win.cc

Issue 418004: This adds the first version of SyncSocket to base, along with a trivial unitt... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 1 month 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 | Annotate | Revision Log
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/sync_socket.h"
6 #include <limits.h>
7 #include <stdio.h>
8 #include <windows.h>
9 #include <sys/types.h>
10 #include "base/atomicops.h"
11 #include "base/logging.h"
12
13
14 namespace base {
15
16 namespace {
17 // This prefix used to be appended to pipe names for pipes
18 // created in CreatePair.
19 const wchar_t kPipePrefix[] = L"\\\\.\\pipe\\chrome.sync.";
20 const size_t kPipePrefixSize = arraysize(kPipePrefix);
21 const size_t kPathMax = 28; // print length of process id + pair count.
22 const size_t kPipePathMax = kPipePrefixSize + kPathMax + 1;
23
24 // To avoid users sending negative message lengths to Send/Receive
25 // we clamp message lengths, which are size_t, to no more than INT_MAX.
26 const size_t kMaxMessageLength = static_cast<size_t>(INT_MAX);
27
28 const int kOutBufferSize = 4096;
29 const int kInBufferSize = 4096;
30 const int kDefaultTimeoutMilliSeconds = 1000;
31
32 static const SyncSocket::Handle kInvalidHandle = INVALID_HANDLE_VALUE;
33
34 } // namespace
35
36 bool SyncSocket::CreatePair(SyncSocket* pair[2]) {
37 Handle handles[2];
38 SyncSocket* tmp_sockets[2];
39
40 // Create the two SyncSocket objects first to avoid ugly cleanup issues.
41 tmp_sockets[0] = new SyncSocket(kInvalidHandle);
42 if (tmp_sockets[0] == NULL) {
43 return false;
44 }
45 tmp_sockets[1] = new SyncSocket(kInvalidHandle);
46 if (tmp_sockets[1] == NULL) {
47 delete tmp_sockets[0];
48 return false;
49 }
50
51 wchar_t name[kPipePathMax];
52 do {
53 unsigned int rnd_name;
54 if (rand_s(&rnd_name) != 0)
55 return false;
56 swprintf(name, kPipePathMax, L"%s%u.%lu",
57 kPipePrefix, GetCurrentProcessId(),
58 rnd_name);
59 handles[0] = CreateNamedPipeW(
60 name,
61 PIPE_ACCESS_DUPLEX | FILE_FLAG_FIRST_PIPE_INSTANCE,
62 PIPE_TYPE_BYTE | PIPE_READMODE_BYTE,
63 1,
64 kOutBufferSize,
65 kInBufferSize,
66 kDefaultTimeoutMilliSeconds,
67 NULL);
68 if (handles[0] == INVALID_HANDLE_VALUE &&
69 GetLastError() != ERROR_ACCESS_DENIED &&
70 GetLastError() != ERROR_PIPE_BUSY) {
71 return false;
72 }
73 } while (handles[0] == INVALID_HANDLE_VALUE);
74 handles[1] = CreateFileW(name,
75 GENERIC_READ | GENERIC_WRITE,
76 0, // no sharing.
77 NULL, // default security attributes.
78 OPEN_EXISTING, // opens existing pipe.
79 SECURITY_SQOS_PRESENT | SECURITY_ANONYMOUS,
80 // no impersonation.
81 NULL); // no template file.
82 if (handles[1] == INVALID_HANDLE_VALUE) {
83 CloseHandle(handles[0]);
84 return false;
85 }
86 if (ConnectNamedPipe(handles[0], NULL) == FALSE) {
87 DWORD error = GetLastError();
88 if (error != ERROR_PIPE_CONNECTED) {
89 CloseHandle(handles[0]);
90 CloseHandle(handles[1]);
91 return false;
92 }
93 }
94 // Copy the handles out for successful return.
95 tmp_sockets[0]->handle_ = handles[0];
96 pair[0] = tmp_sockets[0];
97 tmp_sockets[1]->handle_ = handles[1];
98 pair[1] = tmp_sockets[1];
99 return true;
100 }
101
102 bool SyncSocket::Close() {
103 if (handle_ == kInvalidHandle) {
104 return false;
105 }
106 BOOL retval = CloseHandle(handle_);
107 handle_ = kInvalidHandle;
108 return retval ? true : false;
109 }
110
111 size_t SyncSocket::Send(const void* buffer, size_t length) {
112 DCHECK(length <= kMaxMessageLength);
113 size_t count = 0;
114 while (count < length) {
115 DWORD len;
116 // The following statement is for 64 bit portability.
117 DWORD chunk = static_cast<DWORD>(
118 ((length - count) <= UINT_MAX) ? (length - count) : UINT_MAX);
119 if (WriteFile(handle_, static_cast<const char*>(buffer) + count,
120 chunk, &len, NULL) == FALSE) {
121 return (0 < count) ? count : 0;
122 }
123 count += len;
124 }
125 return count;
126 }
127
128 size_t SyncSocket::Receive(void* buffer, size_t length) {
129 DCHECK(length <= kMaxMessageLength);
130 size_t count = 0;
131 while (count < length) {
132 DWORD len;
133 DWORD chunk = static_cast<DWORD>(
134 ((length - count) <= UINT_MAX) ? (length - count) : UINT_MAX);
135 if (ReadFile(handle_, static_cast<char*>(buffer) + count,
136 chunk, &len, NULL) == FALSE) {
137 return (0 < count) ? count : 0;
138 }
139 count += len;
140 }
141 return count;
142 }
143
144 } // namespace base
OLDNEW
« base/sync_socket.h ('K') | « base/sync_socket.h ('k') | ipc/ipc.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698