aboutsummaryrefslogtreecommitdiffstats
path: root/emulator
diff options
context:
space:
mode:
authorJesse Hall <jessehall@google.com>2012-07-11 16:25:37 -0700
committerJesse Hall <jessehall@google.com>2012-07-11 16:45:58 -0700
commitdca7f2a6ac56567850e0e03a063e1739e43c5ce2 (patch)
treedb0b5bd48d23a9bd1e03c23f1995802222516775 /emulator
parent310777dae93bc4e402ec8a807ce3151271d1038b (diff)
downloadsdk-dca7f2a6ac56567850e0e03a063e1739e43c5ce2.zip
sdk-dca7f2a6ac56567850e0e03a063e1739e43c5ce2.tar.gz
sdk-dca7f2a6ac56567850e0e03a063e1739e43c5ce2.tar.bz2
Use a per-process server address for the GLES server
Previously we used a hardcoded address (tcp port, unix pipe path, etc.) for the OpenGLRender system. Multiple emulators would all try to listen on the same address, with the system non-deterministically (?) choosing which one accepted each new connection. This resulted in frames going to the wrong emulator window, one emulator shutting down another's OpenGL system, etc. Now the OpenGLRender server requests an unused tcp port or derives a path from the pid, and reports the address back to the emulator client to use for future connections from the guest. Change-Id: I6af2eac0c7f27670a3b6595772eebc7aa2b24688
Diffstat (limited to 'emulator')
-rw-r--r--emulator/opengl/host/include/libOpenglRender/render_api.h15
-rw-r--r--emulator/opengl/host/libs/libOpenglRender/RenderServer.cpp16
-rw-r--r--emulator/opengl/host/libs/libOpenglRender/RenderServer.h2
-rw-r--r--emulator/opengl/host/libs/libOpenglRender/render_api.cpp11
-rw-r--r--emulator/opengl/host/renderer/main.cpp11
-rw-r--r--emulator/opengl/shared/OpenglCodecCommon/SocketStream.h5
-rw-r--r--emulator/opengl/shared/OpenglCodecCommon/TcpStream.cpp23
-rw-r--r--emulator/opengl/shared/OpenglCodecCommon/TcpStream.h4
-rw-r--r--emulator/opengl/shared/OpenglCodecCommon/UnixStream.cpp17
-rw-r--r--emulator/opengl/shared/OpenglCodecCommon/UnixStream.h4
-rw-r--r--emulator/opengl/shared/OpenglCodecCommon/Win32PipeStream.cpp15
-rw-r--r--emulator/opengl/shared/OpenglCodecCommon/Win32PipeStream.h4
12 files changed, 72 insertions, 55 deletions
diff --git a/emulator/opengl/host/include/libOpenglRender/render_api.h b/emulator/opengl/host/include/libOpenglRender/render_api.h
index 4fe54f4..527aba1 100644
--- a/emulator/opengl/host/include/libOpenglRender/render_api.h
+++ b/emulator/opengl/host/include/libOpenglRender/render_api.h
@@ -59,14 +59,21 @@ DECL(int, initLibrary, (void));
DECL(int, setStreamMode, (int mode));
/* initOpenGLRenderer - initialize the OpenGL renderer process.
- * portNum is the tcp port number the renderer is listening to.
- * width and height are the framebuffer dimensions that will be
- * reported to the guest display driver.
+ *
+ * width and height are the framebuffer dimensions that will be reported to the
+ * guest display driver.
+ *
+ * addr is a buffer of addrLen bytes that will receive the address that clients
+ * should connect to. The interpretation depends on the transport:
+ * - TCP: The buffer contains the port number as a string. The server is
+ * listening only on the loopback address.
+ * - Win32 and UNIX named pipes: The buffer contains the full path clients
+ * should connect to.
*
* This function is *NOT* thread safe and should be called first
* to initialize the renderer after initLibrary().
*/
-DECL(int, initOpenGLRenderer, (int width, int height, int portNum));
+DECL(int, initOpenGLRenderer, (int width, int height, char* addr, size_t addrLen));
/* getHardwareStrings - describe the GPU hardware and driver.
* The underlying GL's vendor/renderer/version strings are returned to the
diff --git a/emulator/opengl/host/libs/libOpenglRender/RenderServer.cpp b/emulator/opengl/host/libs/libOpenglRender/RenderServer.cpp
index 938a96b..c726e00 100644
--- a/emulator/opengl/host/libs/libOpenglRender/RenderServer.cpp
+++ b/emulator/opengl/host/libs/libOpenglRender/RenderServer.cpp
@@ -40,7 +40,7 @@ RenderServer::~RenderServer()
extern "C" int gRendererStreamMode;
-RenderServer *RenderServer::create(int port)
+RenderServer *RenderServer::create(char* addr, size_t addrLen)
{
RenderServer *server = new RenderServer();
if (!server) {
@@ -57,12 +57,22 @@ RenderServer *RenderServer::create(int port)
#endif
}
- if (server->m_listenSock->listen(port) < 0) {
- ERR("RenderServer::create failed to listen on port %d\n", port);
+ char addrstr[SocketStream::MAX_ADDRSTR_LEN];
+ if (server->m_listenSock->listen(addrstr) < 0) {
+ ERR("RenderServer::create failed to listen\n");
delete server;
return NULL;
}
+ size_t len = strlen(addrstr) + 1;
+ if (len > addrLen) {
+ ERR("RenderServer address name too big for provided buffer: %zu > %zu\n",
+ len, addrLen);
+ delete server;
+ return NULL;
+ }
+ memcpy(addr, addrstr, len);
+
return server;
}
diff --git a/emulator/opengl/host/libs/libOpenglRender/RenderServer.h b/emulator/opengl/host/libs/libOpenglRender/RenderServer.h
index c1f0a08..18b4442 100644
--- a/emulator/opengl/host/libs/libOpenglRender/RenderServer.h
+++ b/emulator/opengl/host/libs/libOpenglRender/RenderServer.h
@@ -22,7 +22,7 @@
class RenderServer : public osUtils::Thread
{
public:
- static RenderServer *create(int port);
+ static RenderServer *create(char* addr, size_t addrLen);
virtual ~RenderServer();
virtual int Main();
diff --git a/emulator/opengl/host/libs/libOpenglRender/render_api.cpp b/emulator/opengl/host/libs/libOpenglRender/render_api.cpp
index 72cd9ba..5c9ffb1 100644
--- a/emulator/opengl/host/libs/libOpenglRender/render_api.cpp
+++ b/emulator/opengl/host/libs/libOpenglRender/render_api.cpp
@@ -33,7 +33,7 @@
static osUtils::childProcess *s_renderProc = NULL;
static RenderServer *s_renderThread = NULL;
-static int s_renderPort = 0;
+static char s_renderAddr[256];
static IOStream *createRenderThread(int p_stream_buffer_size,
unsigned int clientFlags);
@@ -76,7 +76,7 @@ int initLibrary(void)
return true;
}
-int initOpenGLRenderer(int width, int height, int portNum)
+int initOpenGLRenderer(int width, int height, char* addr, size_t addrLen)
{
//
@@ -86,8 +86,6 @@ int initOpenGLRenderer(int width, int height, int portNum)
return false;
}
- s_renderPort = portNum;
-
#ifdef RENDER_API_USE_THREAD // should be defined for mac
//
// initialize the renderer and listen to connections
@@ -98,10 +96,11 @@ int initOpenGLRenderer(int width, int height, int portNum)
return false;
}
- s_renderThread = RenderServer::create(portNum);
+ s_renderThread = RenderServer::create(addr, addrLen);
if (!s_renderThread) {
return false;
}
+ strncpy(s_renderAddr, addr, sizeof(s_renderAddr));
s_renderThread->start();
@@ -345,7 +344,7 @@ IOStream *createRenderThread(int p_stream_buffer_size, unsigned int clientFlags)
ERR("createRenderThread failed to create stream\n");
return NULL;
}
- if (stream->connect(s_renderPort) < 0) {
+ if (stream->connect(s_renderAddr) < 0) {
ERR("createRenderThread failed to connect\n");
delete stream;
return NULL;
diff --git a/emulator/opengl/host/renderer/main.cpp b/emulator/opengl/host/renderer/main.cpp
index 4549c56..d2e3f72 100644
--- a/emulator/opengl/host/renderer/main.cpp
+++ b/emulator/opengl/host/renderer/main.cpp
@@ -34,7 +34,6 @@ static void printUsage(const char *progName)
{
fprintf(stderr, "Usage: %s -windowid <windowid> [options]\n", progName);
fprintf(stderr, " -windowid <windowid> - window id to render into\n");
- fprintf(stderr, " -port <portNum> - listening TCP port number\n");
fprintf(stderr, " -x <num> - render subwindow x position\n");
fprintf(stderr, " -y <num> - render subwindow y position\n");
fprintf(stderr, " -width <num> - render subwindow width\n");
@@ -44,7 +43,6 @@ static void printUsage(const char *progName)
int main(int argc, char *argv[])
{
- int portNum = CODEC_SERVER_PORT;
int winX = 0;
int winY = 0;
int winWidth = 320;
@@ -61,11 +59,6 @@ int main(int argc, char *argv[])
printUsage(argv[0]);
}
}
- else if (!strncmp(argv[i], "-port", 5)) {
- if (++i >= argc || sscanf(argv[i],"%d", &portNum) != 1) {
- printUsage(argv[0]);
- }
- }
else if (!strncmp(argv[i], "-x", 2)) {
if (++i >= argc || sscanf(argv[i],"%d", &winX) != 1) {
printUsage(argv[0]);
@@ -136,11 +129,13 @@ int main(int argc, char *argv[])
//
// Create and run a render server listening to the given port number
//
- RenderServer *server = RenderServer::create(portNum);
+ char addr[256];
+ RenderServer *server = RenderServer::create(addr, sizeof(addr));
if (!server) {
fprintf(stderr,"Cannot initialize render server\n");
return -1;
}
+ printf("render server listening at '%s'\n", addr);
#ifndef _WIN32
//
diff --git a/emulator/opengl/shared/OpenglCodecCommon/SocketStream.h b/emulator/opengl/shared/OpenglCodecCommon/SocketStream.h
index 3a501b4..b0a481b 100644
--- a/emulator/opengl/shared/OpenglCodecCommon/SocketStream.h
+++ b/emulator/opengl/shared/OpenglCodecCommon/SocketStream.h
@@ -22,13 +22,14 @@
class SocketStream : public IOStream {
public:
typedef enum { ERR_INVALID_SOCKET = -1000 } SocketStreamError;
+ static const size_t MAX_ADDRSTR_LEN = 256;
explicit SocketStream(size_t bufsize = 10000);
virtual ~SocketStream();
- virtual int listen(unsigned short port) = 0;
+ virtual int listen(char addrstr[MAX_ADDRSTR_LEN]) = 0;
virtual SocketStream *accept() = 0;
- virtual int connect(unsigned short port) = 0;
+ virtual int connect(const char* addr) = 0;
virtual void *allocBuffer(size_t minSize);
virtual int commitBuffer(size_t size);
diff --git a/emulator/opengl/shared/OpenglCodecCommon/TcpStream.cpp b/emulator/opengl/shared/OpenglCodecCommon/TcpStream.cpp
index 4da2cec..8a6e56e 100644
--- a/emulator/opengl/shared/OpenglCodecCommon/TcpStream.cpp
+++ b/emulator/opengl/shared/OpenglCodecCommon/TcpStream.cpp
@@ -28,6 +28,8 @@
#include <ws2tcpip.h>
#endif
+#define LISTEN_BACKLOG 4
+
TcpStream::TcpStream(size_t bufSize) :
SocketStream(bufSize)
{
@@ -47,10 +49,22 @@ TcpStream::TcpStream(int sock, size_t bufSize) :
setsockopt( sock, IPPROTO_TCP, TCP_NODELAY, (const char*)&flag, sizeof(flag) );
}
-int TcpStream::listen(unsigned short port)
+int TcpStream::listen(char addrstr[MAX_ADDRSTR_LEN])
{
- m_sock = socket_loopback_server(port, SOCK_STREAM);
- if (!valid()) return int(ERR_INVALID_SOCKET);
+ m_sock = socket_loopback_server(0, SOCK_STREAM);
+ if (!valid())
+ return int(ERR_INVALID_SOCKET);
+
+ /* get the actual port number assigned by the system */
+ struct sockaddr_in addr;
+ socklen_t addrLen = sizeof(addr);
+ memset(&addr, 0, sizeof(addr));
+ if (getsockname(m_sock, (struct sockaddr*)&addr, &addrLen) < 0) {
+ close(m_sock);
+ return int(ERR_INVALID_SOCKET);
+ }
+ snprintf(addrstr, MAX_ADDRSTR_LEN - 1, "%hu", ntohs(addr.sin_port));
+ addrstr[MAX_ADDRSTR_LEN-1] = '\0';
return 0;
}
@@ -78,8 +92,9 @@ SocketStream * TcpStream::accept()
return clientStream;
}
-int TcpStream::connect(unsigned short port)
+int TcpStream::connect(const char* addr)
{
+ int port = atoi(addr);
return connect("127.0.0.1",port);
}
diff --git a/emulator/opengl/shared/OpenglCodecCommon/TcpStream.h b/emulator/opengl/shared/OpenglCodecCommon/TcpStream.h
index 811a871..f5b462b 100644
--- a/emulator/opengl/shared/OpenglCodecCommon/TcpStream.h
+++ b/emulator/opengl/shared/OpenglCodecCommon/TcpStream.h
@@ -21,9 +21,9 @@
class TcpStream : public SocketStream {
public:
explicit TcpStream(size_t bufsize = 10000);
- virtual int listen(unsigned short port);
+ virtual int listen(char addrstr[MAX_ADDRSTR_LEN]);
virtual SocketStream *accept();
- virtual int connect(unsigned short port);
+ virtual int connect(const char* addr);
int connect(const char* hostname, unsigned short port);
private:
TcpStream(int sock, size_t bufSize);
diff --git a/emulator/opengl/shared/OpenglCodecCommon/UnixStream.cpp b/emulator/opengl/shared/OpenglCodecCommon/UnixStream.cpp
index 8e463a3..b2eef6d 100644
--- a/emulator/opengl/shared/OpenglCodecCommon/UnixStream.cpp
+++ b/emulator/opengl/shared/OpenglCodecCommon/UnixStream.cpp
@@ -86,15 +86,13 @@ make_unix_path(char *path, size_t pathlen, int port_number)
}
-int UnixStream::listen(unsigned short port)
+int UnixStream::listen(char addrstr[MAX_ADDRSTR_LEN])
{
- char path[PATH_MAX];
-
- if (make_unix_path(path, sizeof(path), port) < 0) {
+ if (make_unix_path(addrstr, MAX_ADDRSTR_LEN, getpid()) < 0) {
return -1;
}
- m_sock = socket_local_server(path, ANDROID_SOCKET_NAMESPACE_FILESYSTEM, SOCK_STREAM);
+ m_sock = socket_local_server(addrstr, ANDROID_SOCKET_NAMESPACE_FILESYSTEM, SOCK_STREAM);
if (!valid()) return int(ERR_INVALID_SOCKET);
return 0;
@@ -123,14 +121,9 @@ SocketStream * UnixStream::accept()
return clientStream;
}
-int UnixStream::connect(unsigned short port)
+int UnixStream::connect(const char* addr)
{
- char path[PATH_MAX];
-
- if (make_unix_path(path, sizeof(path), port) < 0)
- return -1;
-
- m_sock = socket_local_client(path, ANDROID_SOCKET_NAMESPACE_FILESYSTEM, SOCK_STREAM);
+ m_sock = socket_local_client(addr, ANDROID_SOCKET_NAMESPACE_FILESYSTEM, SOCK_STREAM);
if (!valid()) return -1;
return 0;
diff --git a/emulator/opengl/shared/OpenglCodecCommon/UnixStream.h b/emulator/opengl/shared/OpenglCodecCommon/UnixStream.h
index c184b19..95e7431 100644
--- a/emulator/opengl/shared/OpenglCodecCommon/UnixStream.h
+++ b/emulator/opengl/shared/OpenglCodecCommon/UnixStream.h
@@ -21,9 +21,9 @@
class UnixStream : public SocketStream {
public:
explicit UnixStream(size_t bufsize = 10000);
- virtual int listen(unsigned short port);
+ virtual int listen(char addrstr[MAX_ADDRSTR_LEN]);
virtual SocketStream *accept();
- virtual int connect(unsigned short port);
+ virtual int connect(const char* addr);
private:
UnixStream(int sock, size_t bufSize);
};
diff --git a/emulator/opengl/shared/OpenglCodecCommon/Win32PipeStream.cpp b/emulator/opengl/shared/OpenglCodecCommon/Win32PipeStream.cpp
index e1a0b9b..76907a0 100644
--- a/emulator/opengl/shared/OpenglCodecCommon/Win32PipeStream.cpp
+++ b/emulator/opengl/shared/OpenglCodecCommon/Win32PipeStream.cpp
@@ -73,10 +73,10 @@ make_pipe_name(char *path, size_t pathlen, int port_number)
* Also, connect() must create a pipe handle with CreateFile() and
* wait for a server instance with WaitNamedPipe()
*/
-int Win32PipeStream::listen(unsigned short port)
+int Win32PipeStream::listen(char addrstr[MAX_ADDRSTR_LEN])
{
- // just save the port number for accept()
- m_port = port;
+ m_port = GetCurrentProcessId();
+ make_pipe_name(addrstr, MAX_ADDRSTR_LEN, m_port);
return 0;
}
@@ -120,20 +120,17 @@ SocketStream * Win32PipeStream::accept()
return clientStream;
}
-int Win32PipeStream::connect(unsigned short port)
+int Win32PipeStream::connect(const char* addr)
{
- char path[NAMED_PIPE_MAX+1];
HANDLE pipe;
int tries = 10;
- make_pipe_name(path, sizeof(path), port);
-
/* We're going to loop in order to wait for the pipe server to
* be setup properly.
*/
for (; tries > 0; tries--) {
pipe = ::CreateFile(
- path, // pipe name
+ addr, // pipe name
GENERIC_READ | GENERIC_WRITE, // read & write
0, // no sharing
NULL, // default security attrs
@@ -161,7 +158,7 @@ int Win32PipeStream::connect(unsigned short port)
}
/* Wait for 5 seconds */
- if ( !WaitNamedPipe(path, 5000) ) {
+ if ( !WaitNamedPipe(addr, 5000) ) {
ERR("%s: WaitNamedPipe failed: %d\n", __FUNCTION__, (int)GetLastError());
errno = EINVAL;
return -1;
diff --git a/emulator/opengl/shared/OpenglCodecCommon/Win32PipeStream.h b/emulator/opengl/shared/OpenglCodecCommon/Win32PipeStream.h
index 4114545..0897e55 100644
--- a/emulator/opengl/shared/OpenglCodecCommon/Win32PipeStream.h
+++ b/emulator/opengl/shared/OpenglCodecCommon/Win32PipeStream.h
@@ -23,9 +23,9 @@ class Win32PipeStream : public SocketStream {
public:
explicit Win32PipeStream(size_t bufsize = 10000);
virtual ~Win32PipeStream();
- virtual int listen(unsigned short port);
+ virtual int listen(char addrstr[MAX_ADDRSTR_LEN]);
virtual SocketStream *accept();
- virtual int connect(unsigned short port);
+ virtual int connect(const char* addr);
virtual int commitBuffer(size_t size);
virtual const unsigned char *readFully(void *buf, size_t len);