aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Nicolas Noble <nicolasnoble@users.noreply.github.com>2015-09-03 17:08:31 -0700
committerGravatar Nicolas Noble <nicolasnoble@users.noreply.github.com>2015-09-03 17:08:31 -0700
commit8d6536e75551b3c43e71e49c0cb0cbc179ac9f4a (patch)
treeea675ca494966bcb0020cea783e1ba8beb01a2db
parent2b5255e3dafb970c2ad6b9a8382d2a7d8165a9e6 (diff)
parentfa62267c78a86f6fee39477d6424e20ed5245fa5 (diff)
Merge pull request #3236 from ctiller/insert-branch-name
Moar Windows fixes
-rw-r--r--src/core/iomgr/iomgr.c26
-rw-r--r--src/core/iomgr/tcp_client_windows.c39
-rw-r--r--src/core/support/sync_win32.c4
-rwxr-xr-xtools/run_tests/run_tests.py9
4 files changed, 34 insertions, 44 deletions
diff --git a/src/core/iomgr/iomgr.c b/src/core/iomgr/iomgr.c
index fdc9adf4af..1dd03992ae 100644
--- a/src/core/iomgr/iomgr.c
+++ b/src/core/iomgr/iomgr.c
@@ -108,8 +108,14 @@ static size_t count_objects(void) {
return n;
}
-void grpc_iomgr_shutdown(void) {
+static void dump_objects(const char *kind) {
grpc_iomgr_object *obj;
+ for (obj = g_root_object.next; obj != &g_root_object; obj = obj->next) {
+ gpr_log(GPR_DEBUG, "%s OBJECT: %s %p", kind, obj->name, obj);
+ }
+}
+
+void grpc_iomgr_shutdown(void) {
grpc_iomgr_closure *closure;
gpr_timespec shutdown_deadline = gpr_time_add(
gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_seconds(10, GPR_TIMESPAN));
@@ -151,12 +157,14 @@ void grpc_iomgr_shutdown(void) {
}
if (g_root_object.next != &g_root_object) {
int timeout = 0;
- gpr_timespec short_deadline = gpr_time_add(
+ while (g_cbs_head == NULL) {
+ gpr_timespec short_deadline = gpr_time_add(
gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_millis(100, GPR_TIMESPAN));
- while (gpr_cv_wait(&g_rcv, &g_mu, short_deadline) && g_cbs_head == NULL) {
- if (gpr_time_cmp(gpr_now(GPR_CLOCK_REALTIME), shutdown_deadline) > 0) {
- timeout = 1;
- break;
+ if (gpr_cv_wait(&g_rcv, &g_mu, short_deadline) && g_cbs_head == NULL) {
+ if (gpr_time_cmp(gpr_now(GPR_CLOCK_REALTIME), shutdown_deadline) > 0) {
+ timeout = 1;
+ break;
+ }
}
}
if (timeout) {
@@ -164,9 +172,7 @@ void grpc_iomgr_shutdown(void) {
"Failed to free %d iomgr objects before shutdown deadline: "
"memory leaks are likely",
count_objects());
- for (obj = g_root_object.next; obj != &g_root_object; obj = obj->next) {
- gpr_log(GPR_DEBUG, "LEAKED OBJECT: %s %p", obj->name, obj);
- }
+ dump_objects("LEAKED");
break;
}
}
@@ -188,7 +194,7 @@ void grpc_iomgr_register_object(grpc_iomgr_object *obj, const char *name) {
obj->name = gpr_strdup(name);
gpr_mu_lock(&g_mu);
obj->next = &g_root_object;
- obj->prev = obj->next->prev;
+ obj->prev = g_root_object.prev;
obj->next->prev = obj->prev->next = obj;
gpr_mu_unlock(&g_mu);
}
diff --git a/src/core/iomgr/tcp_client_windows.c b/src/core/iomgr/tcp_client_windows.c
index 665ef2885f..05198dbff4 100644
--- a/src/core/iomgr/tcp_client_windows.c
+++ b/src/core/iomgr/tcp_client_windows.c
@@ -60,13 +60,13 @@ typedef struct {
grpc_alarm alarm;
char *addr_name;
int refs;
- int aborted;
} async_connect;
-static void async_connect_cleanup(async_connect *ac) {
+static void async_connect_unlock_and_cleanup(async_connect *ac) {
int done = (--ac->refs == 0);
gpr_mu_unlock(&ac->mu);
if (done) {
+ if (ac->socket != NULL) grpc_winsocket_destroy(ac->socket);
gpr_mu_destroy(&ac->mu);
gpr_free(ac->addr_name);
gpr_free(ac);
@@ -77,10 +77,11 @@ static void on_alarm(void *acp, int occured) {
async_connect *ac = acp;
gpr_mu_lock(&ac->mu);
/* If the alarm didn't occur, it got cancelled. */
+ gpr_log(GPR_DEBUG, "on_alarm: %p", ac->socket);
if (ac->socket != NULL && occured) {
grpc_winsocket_shutdown(ac->socket);
}
- async_connect_cleanup(ac);
+ async_connect_unlock_and_cleanup(ac);
}
static void on_connect(void *acp, int from_iocp) {
@@ -90,12 +91,12 @@ static void on_connect(void *acp, int from_iocp) {
grpc_winsocket_callback_info *info = &ac->socket->write_info;
void (*cb)(void *arg, grpc_endpoint *tcp) = ac->cb;
void *cb_arg = ac->cb_arg;
- int aborted;
-
+
grpc_alarm_cancel(&ac->alarm);
gpr_mu_lock(&ac->mu);
- aborted = ac->aborted;
+
+ gpr_log(GPR_DEBUG, "on_connect: %p", ac->socket);
if (from_iocp) {
DWORD transfered_bytes = 0;
@@ -107,31 +108,16 @@ static void on_connect(void *acp, int from_iocp) {
char *utf8_message = gpr_format_message(WSAGetLastError());
gpr_log(GPR_ERROR, "on_connect error: %s", utf8_message);
gpr_free(utf8_message);
- } else if (!aborted) {
+ } else {
ep = grpc_tcp_create(ac->socket, ac->addr_name);
+ ac->socket = NULL;
}
- } else {
- gpr_log(GPR_ERROR, "on_connect is shutting down");
- /* If the connection timeouts, we will still get a notification from
- the IOCP whatever happens. So we're just going to flag that connection
- as being in the process of being aborted, and wait for the IOCP. We
- can't just orphan the socket now, because the IOCP might already have
- gotten a successful connection, which is our worst-case scenario.
- We need to call our callback now to respect the deadline. */
- ac->aborted = 1;
- gpr_mu_unlock(&ac->mu);
- cb(cb_arg, NULL);
- return;
}
- /* If we don't have an endpoint, it means the connection failed,
- so it doesn't matter if it aborted or failed. We need to orphan
- that socket. */
- if (!ep || aborted) grpc_winsocket_destroy(ac->socket);
- async_connect_cleanup(ac);
+ async_connect_unlock_and_cleanup(ac);
/* If the connection was aborted, the callback was already called when
the deadline was met. */
- if (!aborted) cb(cb_arg, ep);
+ cb(cb_arg, ep);
}
/* Tries to issue one async connection, then schedules both an IOCP
@@ -212,7 +198,6 @@ void grpc_tcp_client_connect(void (*cb)(void *arg, grpc_endpoint *tcp),
gpr_mu_init(&ac->mu);
ac->refs = 2;
ac->addr_name = grpc_sockaddr_to_uri(addr);
- ac->aborted = 0;
grpc_alarm_init(&ac->alarm, deadline, on_alarm, ac,
gpr_now(GPR_CLOCK_MONOTONIC));
@@ -223,7 +208,7 @@ failure:
utf8_message = gpr_format_message(WSAGetLastError());
gpr_log(GPR_ERROR, message, utf8_message);
gpr_free(utf8_message);
- if (socket) {
+ if (socket != NULL) {
grpc_winsocket_destroy(socket);
} else if (sock != INVALID_SOCKET) {
closesocket(sock);
diff --git a/src/core/support/sync_win32.c b/src/core/support/sync_win32.c
index df23492171..f546477067 100644
--- a/src/core/support/sync_win32.c
+++ b/src/core/support/sync_win32.c
@@ -88,9 +88,9 @@ int gpr_cv_wait(gpr_cv *cv, gpr_mu *mu, gpr_timespec abs_deadline) {
SleepConditionVariableCS(cv, &mu->cs, INFINITE);
} else {
gpr_timespec now = gpr_now(abs_deadline.clock_type);
- gpr_int64 now_ms = now.tv_sec * 1000 + now.tv_nsec / 1000000;
+ gpr_int64 now_ms = (gpr_int64)now.tv_sec * 1000 + now.tv_nsec / 1000000;
gpr_int64 deadline_ms =
- abs_deadline.tv_sec * 1000 + abs_deadline.tv_nsec / 1000000;
+ (gpr_int64)abs_deadline.tv_sec * 1000 + abs_deadline.tv_nsec / 1000000;
if (now_ms >= deadline_ms) {
timeout = 1;
} else {
diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py
index 03a873c904..8f6511b1f8 100755
--- a/tools/run_tests/run_tests.py
+++ b/tools/run_tests/run_tests.py
@@ -478,11 +478,10 @@ if len(build_configs) > 1:
if platform.system() == 'Windows':
def make_jobspec(cfg, targets):
extra_args = []
- if args.travis:
- # better do parallel compilation
- extra_args.extend(["/m"])
- # disable PDB generation: it's broken, and we don't need it during CI
- extra_args.extend(["/p:GenerateDebugInformation=false", "/p:DebugInformationFormat=None"])
+ # better do parallel compilation
+ extra_args.extend(["/m"])
+ # disable PDB generation: it's broken, and we don't need it during CI
+ extra_args.extend(["/p:GenerateDebugInformation=false", "/p:DebugInformationFormat=None"])
return [
jobset.JobSpec(['vsprojects\\build.bat',
'vsprojects\\%s.sln' % target,