int socketCreatePair(int* fd1, int* fd2) {
#ifndef _WIN32
    int fds[2];
    int ret = ::socketpair(AF_UNIX, SOCK_STREAM, 0, fds);

    if (!ret) {
        socketSetNonBlocking(fds[0]);
        socketSetNonBlocking(fds[1]);
        *fd1 = fds[0];
        *fd2 = fds[1];
    } else {
        DPLOG(ERROR) << "Could not create socket pair\n";
    }
    return ret;
#else /* _WIN32 */
    /* on Windows, select() only works with network sockets, which
     * means we absolutely cannot use Win32 PIPEs to implement
     * socket pairs with the current event loop implementation.
     * We're going to do like Cygwin: create a random pair
     * of localhost TCP sockets and connect them together
     */

    /* first, create the 'server' socket.
     * a port number of 0 means 'any port between 1024 and 5000.
     * see Winsock bind() documentation for details */
    ScopedSocket s0(socketTcpLoopbackServer(0));
    if (s0.get() < 0) {
        return -1;
    }

    // IMPORTANT: Keep the s0 socket in blocking mode, or the accept()
    // below may fail with WSAEWOULDBLOCK randomly.

    /* now connect a client socket to it, we first need to
     * extract the server socket's port number */
    int port = socketGetPort(s0.get());

    ScopedSocket s2(socketTcpLoopbackClient(port));
    if (!s2.valid()) {
        return -1;
    }

    /* we need to accept the connection on the server socket
     * this will create the second socket for the pair
     */
    ScopedSocket s1(socketAccept(s0.get()));
    if (!s1.valid()) {
        DPLOG(ERROR) << "Could not accept connection from server socket\n";
        return -1;
    }
    socketSetNonBlocking(s1.get());

    *fd1 = s1.release();
    *fd2 = s2.release();

    return 0;
#endif /* _WIN32 */
}
Exemple #2
0
		bool ObjectWatcher::StartWatching(HANDLE object, Delegate* delegate) {
			CHECK(delegate);
			if (wait_object_) {
				NOTREACHED() << "Already watching an object";
				return false;
			}

			// Since our job is to just notice when an object is signaled and report the
			// result back to this thread, we can just run on a Windows wait thread.
			DWORD wait_flags = WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE;

			// DoneWaiting can be synchronously called from RegisterWaitForSingleObject,
			// so set up all state now.
			callback_ = base::Bind(&ObjectWatcher::Signal, weak_factory_.GetWeakPtr(),
				delegate);
			object_ = object;
			origin_loop_ = MessageLoop::current();

			if (!RegisterWaitForSingleObject(&wait_object_, object, DoneWaiting,
				this, INFINITE, wait_flags)) {
				DPLOG(FATAL) << "RegisterWaitForSingleObject failed";
				object_ = NULL;
				wait_object_ = NULL;
				return false;
			}

			// We need to know if the current message loop is going away so we can
			// prevent the wait thread from trying to access a dead message loop.
			MessageLoop::current()->AddDestructionObserver(this);
			return true;
		}
Exemple #3
0
void PLogTest()
{
    PLOG(ERROR) << "Couldn't do foo";
    DPLOG(ERROR) << "Couldn't do foo";
    PLOG_IF(ERROR, 1) << "Couldn't do foo";
    DPLOG_IF(ERROR, 0) << "Couldn't do foo";
    PCHECK(1) << "Couldn't do foo";
    DPCHECK(1) << "Couldn't do foo";
}
int socketGetPort(int socket) {
    SockAddressStorage addr;
    socklen_t addrLen = sizeof(addr);
    if (getsockname(socket, &addr.generic, &addrLen) < 0) {
        DPLOG(ERROR) << "Could not get socket name!\n";
        return -1;
    }
    return addr.getPort();
}
int socketTcpLoopbackClient(int port) {
    ScopedSocket s(socketCreateTcp());

    if (s.get() < 0) {
        DPLOG(ERROR) << "Could not create TCP socket\n";
        return -1;
    }

    SockAddressStorage addr;
    addr.initLoopback(port);

    if (::connect(s.get(), &addr.generic, sizeof(addr.inet)) < 0) {
        DPLOG(ERROR) << "Could not connect to TCP loopback port "
                     << port
                     << "\n";
        return -1;
    }

    return s.release();
}
int socketTcpLoopbackServer(int port) {
    ScopedSocket s(socketCreateTcp());

    if (s.get() < 0) {
        DPLOG(ERROR) << "Could not create TCP socket\n";
        return -1;
    }

    socketSetXReuseAddr(s.get());

    SockAddressStorage addr;
    addr.initLoopback(port);

    if (socketTcpBindAndListen(s.get(), &addr) < 0) {
        DPLOG(ERROR) << "Could not bind to TCP loopback port "
                     << port
                     << "\n";
        return -1;
    }

    return s.release();
}
Exemple #7
0
 Win32ErrorLogMessage::~Win32ErrorLogMessage()
 {
     const int error_message_buffer_size = 256;
     char msgbuf[error_message_buffer_size];
     DWORD flags = FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS;
     HMODULE hmod;
     if(module_)
     {
         hmod = GetModuleHandleA(module_);
         if(hmod)
         {
             flags |= FORMAT_MESSAGE_FROM_HMODULE;
         }
         else
         {
             // 导致Win32ErrorLogMessage嵌套, 由于module_是NULL不会再次进入这里,
             // 所以不会死循环.
             DPLOG(WARNING) << "Couldn't open module " << module_
                 << " for error message query";
         }
     }
     else
     {
         hmod = NULL;
     }
     DWORD len = FormatMessageA(flags, hmod, err_,
         MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
         msgbuf, sizeof(msgbuf)/sizeof(msgbuf[0]), NULL);
     if(len)
     {
         while((len>0) && isspace(static_cast<unsigned char>(msgbuf[len-1])))
         {
             msgbuf[--len] = 0;
         }
         stream() << ": " << msgbuf;
     }
     else
     {
         stream() << ": Error " << GetLastError() << " while retrieving error "
             << err_;
     }
 }
Exemple #8
0
		bool ObjectWatcher::StopWatching() {
			if (!wait_object_)
				return false;

			// Make sure ObjectWatcher is used in a single-threaded fashion.
			DCHECK_EQ(origin_loop_, MessageLoop::current());

			// Blocking call to cancel the wait. Any callbacks already in progress will
			// finish before we return from this call.
			if (!UnregisterWaitEx(wait_object_, INVALID_HANDLE_VALUE)) {
				DPLOG(FATAL) << "UnregisterWaitEx failed";
				return false;
			}

			weak_factory_.InvalidateWeakPtrs();
			object_ = NULL;
			wait_object_ = NULL;

			MessageLoop::current()->RemoveDestructionObserver(this);
			return true;
		}