ipc/unixsocket/DataSocket.cpp
author Michael Comella <michael.l.comella@gmail.com>
Tue, 15 Sep 2015 16:46:58 -0700
changeset 266944 ed8188590f14b1aae2e4f44c8196994f375a99f4
parent 253778 e9f9b39c43317d8de56a49427ccbdf27b9647ad0
child 295765 413335e6452af2fb0768056b652953ca5da0fe96
permissions -rw-r--r--
Bug 1201206 - Correct menu button background on 2.3. r=mhaigh One fear is that different devices set different menu colors and text colors. Since we're using the default text color and set an explicit menu color, the text color may not look good on these devices. I was unable to find a way to override the menu text color. It seems the best way to find out if this is a problem is to land it and test though!

/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
/* vim: set ts=2 et sw=2 tw=80: */

/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include "DataSocket.h"
#ifdef MOZ_TASK_TRACER
#include "GeckoTaskTracer.h"
#endif
#include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, MOZ_COUNT_DTOR

#ifdef MOZ_TASK_TRACER
using namespace mozilla::tasktracer;
#endif

namespace mozilla {
namespace ipc {

//
// DataSocketIO
//

DataSocketIO::~DataSocketIO()
{
  MOZ_COUNT_DTOR_INHERITED(DataSocketIO, SocketIOBase);
}

void
DataSocketIO::EnqueueData(UnixSocketIOBuffer* aBuffer)
{
  if (!aBuffer->GetSize()) {
    delete aBuffer; // delete empty data immediately
    return;
  }
  mOutgoingQ.AppendElement(aBuffer);
}

bool
DataSocketIO::HasPendingData() const
{
  return !mOutgoingQ.IsEmpty();
}

ssize_t
DataSocketIO::ReceiveData(int aFd)
{
  MOZ_ASSERT(aFd >= 0);

  UnixSocketIOBuffer* incoming;
  nsresult rv = QueryReceiveBuffer(&incoming);
  if (NS_FAILED(rv)) {
    /* an error occured */
    GetConsumerThread()->PostTask(FROM_HERE,
                                  new SocketRequestClosingTask(this));
    return -1;
  }

  ssize_t res = incoming->Receive(aFd);
  if (res < 0) {
    /* an I/O error occured */
    DiscardBuffer();
    GetConsumerThread()->PostTask(FROM_HERE,
                                  new SocketRequestClosingTask(this));
    return -1;
  } else if (!res) {
    /* EOF or peer shut down sending */
    DiscardBuffer();
    GetConsumerThread()->PostTask(FROM_HERE,
                                  new SocketRequestClosingTask(this));
    return 0;
  }

#ifdef MOZ_TASK_TRACER
  /* Make unix socket creation events to be the source events of TaskTracer,
   * and originate the rest correlation tasks from here.
   */
  AutoSourceEvent taskTracerEvent(SourceEventType::Unixsocket);
#endif

  ConsumeBuffer();

  return res;
}

nsresult
DataSocketIO::SendPendingData(int aFd)
{
  MOZ_ASSERT(aFd >= 0);

  while (HasPendingData()) {
    UnixSocketIOBuffer* outgoing = mOutgoingQ.ElementAt(0);

    ssize_t res = outgoing->Send(aFd);
    if (res < 0) {
      /* an I/O error occured */
      GetConsumerThread()->PostTask(FROM_HERE,
                                    new SocketRequestClosingTask(this));
      return NS_ERROR_FAILURE;
    } else if (!res && outgoing->GetSize()) {
      /* I/O is currently blocked; try again later */
      return NS_OK;
    }
    if (!outgoing->GetSize()) {
      mOutgoingQ.RemoveElementAt(0);
      delete outgoing;
    }
  }

  return NS_OK;
}

DataSocketIO::DataSocketIO(MessageLoop* aConsumerLoop)
  : SocketIOBase(aConsumerLoop)
{
  MOZ_COUNT_CTOR_INHERITED(DataSocketIO, SocketIOBase);
}

//
// DataSocket
//

DataSocket::DataSocket()
{
  MOZ_COUNT_CTOR_INHERITED(DataSocket, SocketBase);
}

DataSocket::~DataSocket()
{
  MOZ_COUNT_DTOR_INHERITED(DataSocket, SocketBase);
}

}
}