UnixOperatingSystem.st
changeset 22643 ca656b9a9b79
parent 22623 a4a3c7bfd522
child 22644 be8a36f6839d
--- a/UnixOperatingSystem.st	Tue Mar 20 22:07:03 2018 +0100
+++ b/UnixOperatingSystem.st	Tue Mar 20 22:40:45 2018 +0100
@@ -10184,7 +10184,7 @@
 #endif
 %}.
     seconds notNil ifTrue:[
-        ^ { ((seconds * 1000) + millis) . micros }
+	^ { ((seconds * 1000) + millis) . micros }
     ].
 
     self primitiveFailed.
@@ -13342,6 +13342,10 @@
     int ret, __flags;
     char *bp;
     int nInstBytes, sockAddrSize;
+    union {
+	struct sockaddr_in addr;
+	char enoughBytesForBigAddresses[1024];
+    } sav_addr;
 
     if (wantHostName == true) {
 	hp = host;
@@ -13376,13 +13380,32 @@
     }
 
     {
+	char *sav_bp;
+
 	bp = (char *)(__byteArrayVal(socketAddress));
 	bp += nInstBytes;
+
+	// when we run this interruptable (or even in a separate thread),
+	// we cannot pass ST/X objects to it
+	// (some other ST/X thread might trigger a GC)
+	if (sockAddrSize <= sizeof(sav_addr)) {
+	    sav_bp = (char *)(&sav_addr.addr);
+	} else {
+	    fprintf(stderr, "OS: sockAddr buffer size too small\n");
+	    sav_bp = (char *)malloc(sockAddrSize + 32);
+	}
+	memcpy(sav_bp, bp, sockAddrSize);
+
 	__BEGIN_INTERRUPTABLE__
-	ret = getnameinfo((struct sockaddr *)bp, sockAddrSize,
+	ret = getnameinfo((struct sockaddr *)sav_bp, sockAddrSize,
 			  hp, hsz, sp, ssz, __flags);
 	__END_INTERRUPTABLE__
+
+	if (sav_bp != (char *)(&sav_addr.addr)) {
+	    free(sav_bp);
+	}
     } while (ret == EAI_SYSTEM && errno == EINTR);
+
     if (ret != 0) {
 	switch (ret) {
 	case EAI_FAMILY: