| Index: sandbox/win/src/sharedmem_ipc_client.cc
|
| diff --git a/sandbox/win/src/sharedmem_ipc_client.cc b/sandbox/win/src/sharedmem_ipc_client.cc
|
| deleted file mode 100644
|
| index eac13937c204d90907232e2dba6862005b9d8782..0000000000000000000000000000000000000000
|
| --- a/sandbox/win/src/sharedmem_ipc_client.cc
|
| +++ /dev/null
|
| @@ -1,153 +0,0 @@
|
| -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#include <stddef.h>
|
| -#include <string.h>
|
| -
|
| -#include "base/logging.h"
|
| -#include "sandbox/win/src/crosscall_client.h"
|
| -#include "sandbox/win/src/crosscall_params.h"
|
| -#include "sandbox/win/src/sandbox.h"
|
| -#include "sandbox/win/src/sharedmem_ipc_client.h"
|
| -
|
| -namespace sandbox {
|
| -
|
| -// Get the base of the data buffer of the channel; this is where the input
|
| -// parameters get serialized. Since they get serialized directly into the
|
| -// channel we avoid one copy.
|
| -void* SharedMemIPCClient::GetBuffer() {
|
| - bool failure = false;
|
| - size_t ix = LockFreeChannel(&failure);
|
| - if (failure) {
|
| - return NULL;
|
| - }
|
| - return reinterpret_cast<char*>(control_) +
|
| - control_->channels[ix].channel_base;
|
| -}
|
| -
|
| -// If we need to cancel an IPC before issuing DoCall
|
| -// our client should call FreeBuffer with the same pointer
|
| -// returned by GetBuffer.
|
| -void SharedMemIPCClient::FreeBuffer(void* buffer) {
|
| - size_t num = ChannelIndexFromBuffer(buffer);
|
| - ChannelControl* channel = control_->channels;
|
| - LONG result = ::InterlockedExchange(&channel[num].state, kFreeChannel);
|
| - DCHECK_NE(kFreeChannel, static_cast<ChannelState>(result));
|
| -}
|
| -
|
| -// The constructor simply casts the shared memory to the internal
|
| -// structures. This is a cheap step that is why this IPC object can
|
| -// and should be constructed per call.
|
| -SharedMemIPCClient::SharedMemIPCClient(void* shared_mem)
|
| - : control_(reinterpret_cast<IPCControl*>(shared_mem)) {
|
| - first_base_ = reinterpret_cast<char*>(shared_mem) +
|
| - control_->channels[0].channel_base;
|
| - // There must be at least one channel.
|
| - DCHECK(0 != control_->channels_count);
|
| -}
|
| -
|
| -// Do the IPC. At this point the channel should have already been
|
| -// filled with the serialized input parameters.
|
| -// We follow the pattern explained in the header file.
|
| -ResultCode SharedMemIPCClient::DoCall(CrossCallParams* params,
|
| - CrossCallReturn* answer) {
|
| - if (!control_->server_alive)
|
| - return SBOX_ERROR_CHANNEL_ERROR;
|
| -
|
| - size_t num = ChannelIndexFromBuffer(params->GetBuffer());
|
| - ChannelControl* channel = control_->channels;
|
| - // Note that the IPC tag goes outside the buffer as well inside
|
| - // the buffer. This should enable the server to prioritize based on
|
| - // IPC tags without having to de-serialize the entire message.
|
| - channel[num].ipc_tag = params->GetTag();
|
| -
|
| - // Wait for the server to service this IPC call. After kIPCWaitTimeOut1
|
| - // we check if the server_alive mutex was abandoned which will indicate
|
| - // that the server has died.
|
| -
|
| - // While the atomic signaling and waiting is not a requirement, it
|
| - // is nice because we save a trip to kernel.
|
| - DWORD wait = ::SignalObjectAndWait(channel[num].ping_event,
|
| - channel[num].pong_event,
|
| - kIPCWaitTimeOut1, FALSE);
|
| - if (WAIT_TIMEOUT == wait) {
|
| - // The server is taking too long. Enter a loop were we check if the
|
| - // server_alive mutex has been abandoned which would signal a server crash
|
| - // or else we keep waiting for a response.
|
| - while (true) {
|
| - wait = ::WaitForSingleObject(control_->server_alive, 0);
|
| - if (WAIT_TIMEOUT == wait) {
|
| - // Server seems still alive. We already signaled so here we just wait.
|
| - wait = ::WaitForSingleObject(channel[num].pong_event, kIPCWaitTimeOut1);
|
| - if (WAIT_OBJECT_0 == wait) {
|
| - // The server took a long time but responded.
|
| - break;
|
| - } else if (WAIT_TIMEOUT == wait) {
|
| - continue;
|
| - } else {
|
| - return SBOX_ERROR_CHANNEL_ERROR;
|
| - }
|
| - } else {
|
| - // The server has crashed and windows has signaled the mutex as
|
| - // abandoned.
|
| - ::InterlockedExchange(&channel[num].state, kAbandonedChannel);
|
| - control_->server_alive = 0;
|
| - return SBOX_ERROR_CHANNEL_ERROR;
|
| - }
|
| - }
|
| - } else if (WAIT_OBJECT_0 != wait) {
|
| - // Probably the server crashed before the kIPCWaitTimeOut1 occurred.
|
| - return SBOX_ERROR_CHANNEL_ERROR;
|
| - }
|
| -
|
| - // The server has returned an answer, copy it and free the channel.
|
| - memcpy(answer, params->GetCallReturn(), sizeof(CrossCallReturn));
|
| -
|
| - // Return the IPC state It can indicate that while the IPC has
|
| - // completed some error in the Broker has caused to not return valid
|
| - // results.
|
| - return answer->call_outcome;
|
| -}
|
| -
|
| -// Locking a channel is a simple as looping over all the channels
|
| -// looking for one that is has state = kFreeChannel and atomically
|
| -// swapping it to kBusyChannel.
|
| -// If there is no free channel, then we must back off so some other
|
| -// thread makes progress and frees a channel. To back off we sleep.
|
| -size_t SharedMemIPCClient::LockFreeChannel(bool* severe_failure) {
|
| - if (0 == control_->channels_count) {
|
| - *severe_failure = true;
|
| - return 0;
|
| - }
|
| - ChannelControl* channel = control_->channels;
|
| - do {
|
| - for (size_t ix = 0; ix != control_->channels_count; ++ix) {
|
| - if (kFreeChannel == ::InterlockedCompareExchange(&channel[ix].state,
|
| - kBusyChannel,
|
| - kFreeChannel)) {
|
| - *severe_failure = false;
|
| - return ix;
|
| - }
|
| - }
|
| - // We did not find any available channel, maybe the server is dead.
|
| - DWORD wait = ::WaitForSingleObject(control_->server_alive,
|
| - kIPCWaitTimeOut2);
|
| - if (WAIT_TIMEOUT != wait) {
|
| - // The server is dead and we outlive it enough to get in trouble.
|
| - *severe_failure = true;
|
| - return 0;
|
| - }
|
| - }
|
| - while (true);
|
| -}
|
| -
|
| -// Find out which channel we are from the pointer returned by GetBuffer.
|
| -size_t SharedMemIPCClient::ChannelIndexFromBuffer(const void* buffer) {
|
| - ptrdiff_t d = reinterpret_cast<const char*>(buffer) - first_base_;
|
| - size_t num = d/kIPCChannelSize;
|
| - DCHECK_LT(num, control_->channels_count);
|
| - return (num);
|
| -}
|
| -
|
| -} // namespace sandbox
|
|
|