diff --git a/Source/Makefile.sed.nt b/Source/Makefile.sed.nt index ae250e251..3438f5747 100644 --- a/Source/Makefile.sed.nt +++ b/Source/Makefile.sed.nt @@ -113,7 +113,7 @@ lib$(LIBRARY_NAME).dll: $(HEADERS_INSTALL) $(OBJS_INSTALL) $(INIT_LIB_OBJ) lib$( link -out:lib$(LIBRARY_NAME).dll $(DLLFLAGS) \\\ lib$(LIBRARY_NAME)-dll.exp \\\ lib$(LIBRARY_NAME)$(LIBEXT) \\\ - win32-entry$(OEXT) libgcc.lib libobjc.lib \\\ + win32-entry$(OEXT) libgcc.lib libobjc-dll.lib \\\ libcmt.lib oldnames.lib user32.lib kernel32.lib wsock32.lib \\\ advapi32.lib\ \ diff --git a/Source/NSProcessInfo.m b/Source/NSProcessInfo.m index f050dde38..cc83dc880 100644 --- a/Source/NSProcessInfo.m +++ b/Source/NSProcessInfo.m @@ -261,6 +261,21 @@ __attribute__ ((section ("_libc_subinit"))) = &(_gnu_process_args); #undef main int main(int argc, char *argv[], char *env[]) { +#ifdef __WIN32__ + WSADATA lpWSAData; + + // Initialize Windows Sockets + if (WSAStartup(MAKEWORD(1,1), &lpWSAData)) + { + printf("Could not startup Windows Sockets\n"); + exit(1); + } +#endif /* __WIN32__ */ + +#ifdef __MS_WIN32__ + _MB_init_runtime(); +#endif /* __MS_WIN32__ */ + _gnu_process_args(argc, argv, env); /* Call the user defined main function */ diff --git a/Source/RunLoop.m b/Source/RunLoop.m index 3252326e6..52a5aedcd 100644 --- a/Source/RunLoop.m +++ b/Source/RunLoop.m @@ -253,9 +253,12 @@ static RunLoop *current_run_loop; fd_set read_fds; /* Copy for listening to read-ready fds. */ fd_set exception_fds; /* Copy for listening to exception fds. */ int select_return; - int fd_index; NSMapTable *fd_2_object; id saved_mode; + id ports; + int num_of_ports; + int port_fd_count = 128; // xxx #define this constant + int port_fd_array[port_fd_count]; assert (mode); saved_mode = _current_mode; @@ -316,6 +319,19 @@ static RunLoop *current_run_loop; fd_2_object = NSCreateMapTable (NSIntMapKeyCallBacks, NSObjectMapValueCallBacks, 0); + /* If a port is invalid, remove it from this mode. */ + ports = NSMapGet (_mode_2_in_ports, mode); + { + id port; + int i; + for (i = [ports count]-1; i >= 0; i--) + { + port = [ports objectAtIndex: i]; + if (![port isValid]) + [ports removeObjectAtIndex: i]; + } + } + num_of_ports = 0; /* Do the pre-listening set-up for the file descriptors of this mode. */ { @@ -323,40 +339,46 @@ static RunLoop *current_run_loop; /* Do the pre-listening set-up for the ports of this mode. */ { - id ports = NSMapGet (_mode_2_in_ports, mode); if (ports) { id port; int i; - - /* If a port is invalid, remove it from this mode. */ - for (i = [ports count]-1; i >= 0; i--) - { - port = [ports objectAtIndex: i]; - if (![port isValid]) - [ports removeObjectAtIndex: i]; - } + int fd_count = port_fd_count; + int fd_array[port_fd_count]; /* Ask our ports for the list of file descriptors they - want us to listen to; add these to FD_LISTEN_SET. */ + want us to listen to; add these to FD_LISTEN_SET. + Save the list of ports for later use. */ for (i = [ports count]-1; i >= 0; i--) { - int port_fd_count = 128; // xxx #define this constant - int port_fd_array[port_fd_count]; port = [ports objectAtIndex: i]; if ([port respondsTo: @selector(getFds:count:)]) - [port getFds: port_fd_array count: &port_fd_count]; + [port getFds: fd_array count: &fd_count]; + else + fd_count = 0; if (debug_run_loop) - printf("\tRunLoop listening to %d sockets\n", port_fd_count); - while (port_fd_count--) + printf("\tRunLoop listening to %d sockets\n", fd_count); + num_of_ports += fd_count; + if (num_of_ports > port_fd_count) { - FD_SET (port_fd_array[port_fd_count], &fds); + /* xxx Uh oh our array isn't big enough */ + perror ("RunLoop attempt to listen to too many ports\n"); + abort (); + } + while (fd_count--) + { + int j = num_of_ports - fd_count - 1; + port_fd_array[j] = fd_array[fd_count]; + FD_SET (port_fd_array[j], &fds); NSMapInsert (fd_2_object, - (void*)port_fd_array[port_fd_count], port); + (void*)port_fd_array[j], + port); } } } } + if (debug_run_loop) + printf("\tRunLoop listening to %d total ports\n", num_of_ports); /* Wait for incoming data, listening to the file descriptors in _FDS. */ read_fds = fds; @@ -383,13 +405,24 @@ static RunLoop *current_run_loop; /* Look at all the file descriptors select() says are ready for reading; notify the corresponding object for each of the ready fd's. */ - for (fd_index = 0; fd_index < FD_SETSIZE; fd_index++) - if (FD_ISSET (fd_index, &read_fds)) + { + if (ports) { - id fd_object = (id) NSMapGet (fd_2_object, (void*)fd_index); - assert (fd_object); - [fd_object readyForReadingOnFileDescriptor: fd_index]; + int i; + + for (i = num_of_ports - 1; i >= 0; i--) + { + if (FD_ISSET (port_fd_array[i], &read_fds)) + { + id fd_object = (id) NSMapGet (fd_2_object, + (void*)port_fd_array[i]); + assert (fd_object); + [fd_object readyForReadingOnFileDescriptor: + port_fd_array[i]]; + } + } } + } /* Clean up before returning. */ NSFreeMapTable (fd_2_object); diff --git a/Source/TcpPort.m b/Source/TcpPort.m index dbf615fc3..9235aa6f8 100644 --- a/Source/TcpPort.m +++ b/Source/TcpPort.m @@ -581,7 +581,11 @@ static NSMapTable* port_number_2_port; getting it. This may help Connection invalidation confusion. However, then the process might run out of FD's if the close() was delayed too long. */ +#ifdef __WIN32__ + closesocket (_socket); +#else close (_socket); +#endif /* These are here, and not in -dealloc, to prevent +newForReceivingFromPortNumber: from returning invalid sockets. */ @@ -988,7 +992,11 @@ static NSMapTable *out_port_bag = NULL; /* xxx Perhaps should delay this close() to keep another port from getting it. This may help Connection invalidation confusion. */ +#ifdef __WIN32__ + if (closesocket (_socket) < 0) +#else if (close (_socket) < 0) +#endif { perror ("[TcpOutPort -invalidate] close()"); abort (); @@ -1112,7 +1120,11 @@ static NSMapTable *out_port_bag = NULL; char prefix_buffer[PREFIX_SIZE]; int c; +#ifdef __WIN32__ + c = recv (s, prefix_buffer, PREFIX_SIZE, 0); +#else c = read (s, prefix_buffer, PREFIX_SIZE); +#endif if (c == 0) { *packet_size = EOF; *rp = nil; @@ -1159,7 +1171,11 @@ static NSMapTable *out_port_bag = NULL; remaining = size - eof_position; /* xxx We need to make sure this read() is non-blocking. */ +#ifdef __WIN32__ + c = recv (s, buffer + prefix + eof_position, remaining, 0); +#else c = read (s, buffer + prefix + eof_position, remaining); +#endif if (c == 0) return EOF; eof_position += c; @@ -1194,7 +1210,11 @@ static NSMapTable *out_port_bag = NULL; memset (buffer + PREFIX_LENGTH_SIZE, 0, PREFIX_ADDRESS_SIZE); /* Write the packet on the socket. */ +#ifdef __WIN32__ + c = send (s, buffer, prefix + eof_position, 0); +#else c = write (s, buffer, prefix + eof_position); +#endif if (c < 0) { perror ("[TcpOutPort -_writeToSocket:] write()"); diff --git a/Source/behavior.m b/Source/behavior.m index 49a1f0016..a237625da 100644 --- a/Source/behavior.m +++ b/Source/behavior.m @@ -65,9 +65,6 @@ static void __objc_class_add_protocols (Class class, static BOOL class_is_kind_of(Class self, Class class); static void check_class_methods(Class class); -/* The uninstalled dispatch table, declared in gcc/objc/sendmsg.c. */ -extern struct sarray* __objc_uninstalled_dtable; - /* xxx consider using sendmsg.c:__objc_update_dispatch_table_for_class, but, I think it will be slower than the current method. */ @@ -203,7 +200,7 @@ behavior_class_add_methods (Class class, the dtable sarray, but if it isn't, let __objc_install_dispatch_table_for_class do it. */ - if (class->dtable != __objc_uninstalled_dtable) + if (class->dtable != objc_get_uninstalled_dtable()) { sarray_at_put_safe (class->dtable, (sidx) method->method_name->sel_id, @@ -436,7 +433,7 @@ check_class_methods(Class class) int counter; MethodList_t mlist; - if (class->dtable == __objc_uninstalled_dtable) + if (class->dtable == objc_get_uninstalled_dtable()) return; for (mlist = class->methods; mlist; mlist = mlist->method_next) diff --git a/Source/objc-load.c b/Source/objc-load.c index 3ebaf573d..267e336e9 100644 --- a/Source/objc-load.c +++ b/Source/objc-load.c @@ -41,7 +41,6 @@ /* From the objc runtime -- needed when invalidating the dtable */ extern void __objc_install_premature_dtable(Class); extern void sarray_free(struct sarray*); -extern struct sarray *__objc_uninstalled_dtable; /* Declaration from NSBundle.m */ const char *objc_executable_location( void ); @@ -86,7 +85,7 @@ objc_invalidate_dtable(Class class) { Class s; - if (class->dtable == __objc_uninstalled_dtable) + if (class->dtable == objc_get_uninstalled_dtable()) return; sarray_free(class->dtable); __objc_install_premature_dtable(class); diff --git a/Testing/Makefile.sed.nt b/Testing/Makefile.sed.nt index f1ce85da4..a48aaff76 100644 --- a/Testing/Makefile.sed.nt +++ b/Testing/Makefile.sed.nt @@ -9,9 +9,23 @@ s/CFLAGS = -Wall -Wno-implicit -Wno-format -g -O/CFLAGS = -Wall -Wno-implicit -W s/EXEEXT =/EXEEXT = .exe/ s/OEXT = .o/OEXT = .obj/ s/LIBEXT = .a/LIBEXT = .lib/ -s/@DEFS@/-DSTDC_HEADERS=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_TIMES=1 -DHAVE_VSPRINTF=1 -Dvm_page_size=4096/ +s/@DEFS@/-DHAVE_CONFIG_H=1/ /%: %$(OEXT)/,/$(CC) $(ALL_CFLAGS) $@$(OEXT)/c\ LINK_CMD = nm $@$(OEXT) | grep " __GLOBAL_" > tmpinit.c \& collect tmpinit.c $@_init_runtime \& $(CC) -c $@_init_runtime.c \& rm tmpinit.c \& ld $@$(OEXT) $@_init_runtime$(OEXT) -o $@$(EXEEXT) $(ALL_LDFLAGS)\ +tcpport-server: tcpport-server$(OEXT) ../src/lib$(LIBRARY_NAME)$(LIBEXT)\ + nm tcpport-server$(OEXT) | grep " __GLOBAL_" > tmpinit.c\ + collect tmpinit.c tcpport_server_init_runtime\ + $(CC) -c tcpport_server_init_runtime.c\ + rm tmpinit.c\ + ld $@$(OEXT) tcpport_server_init_runtime$(OEXT) -o $@$(EXEEXT) $(ALL_LDFLAGS)\ +\ +tcpport-client: tcpport-client$(OEXT) ../src/lib$(LIBRARY_NAME)$(LIBEXT)\ + nm tcpport-client$(OEXT) | grep " __GLOBAL_" > tmpinit.c\ + collect tmpinit.c tcpport_client_init_runtime\ + $(CC) -c tcpport_client_init_runtime.c\ + rm tmpinit.c\ + ld $@$(OEXT) tcpport_client_init_runtime$(OEXT) -o $@$(EXEEXT) $(ALL_LDFLAGS)\ +\ %: %$(OEXT) ../src/lib$(LIBRARY_NAME)$(LIBEXT)\ $(LINK_CMD) s/clean: mostlyclean/clean: mostlyclean\