X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Ftpool-poll.c;h=e03eca5248cc4c4a0f36bb374064bf2eebab1258;hb=a3c37cd9bad84c08e8aacec3ee3fd6f0b9917513;hp=5b1af65fb7583fc738f8d08798cce0edb21227a7;hpb=8138a37d7fe944b71a9fb769b5347c6714e81554;p=mono.git diff --git a/mono/metadata/tpool-poll.c b/mono/metadata/tpool-poll.c index 5b1af65fb75..e03eca5248c 100644 --- a/mono/metadata/tpool-poll.c +++ b/mono/metadata/tpool-poll.c @@ -1,3 +1,14 @@ +/* + * tpool-poll.c: poll related stuff + * + * Authors: + * Dietmar Maurer (dietmar@ximian.com) + * Gonzalo Paniagua Javier (gonzalo@ximian.com) + * + * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com) + * Copyright 2004-2011 Novell, Inc (http://www.novell.com) + */ + #define INIT_POLLFD(a, b, c) {(a)->fd = b; (a)->events = c; (a)->revents = 0;} struct _tp_poll_data { int pipe [2]; @@ -11,30 +22,13 @@ static void tp_poll_shutdown (gpointer event_data); static void tp_poll_modify (gpointer event_data, int fd, int operation, int events, gboolean is_new); static void tp_poll_wait (gpointer p); -#ifdef HOST_WIN32 -static void -connect_hack (gpointer x) -{ - struct sockaddr_in *addr = (struct sockaddr_in *) x; - int count = 0; - - while (connect ((SOCKET) socket_io_data.pipe [1], (SOCKADDR *) addr, sizeof (struct sockaddr_in))) { - Sleep (500); - if (++count > 3) { - g_warning ("Error initializing async. sockets %d.", WSAGetLastError ()); - g_assert (WSAGetLastError ()); - } - } -} -#endif - static gpointer tp_poll_init (SocketIOData *data) { tp_poll_data *result; #ifdef HOST_WIN32 - struct sockaddr_in server; struct sockaddr_in client; + struct sockaddr_in server; SOCKET srv; int len; #endif @@ -55,7 +49,7 @@ tp_poll_init (SocketIOData *data) server.sin_family = AF_INET; server.sin_addr.s_addr = inet_addr ("127.0.0.1"); server.sin_port = 0; - if (bind (srv, (SOCKADDR *) &server, sizeof (server))) { + if (bind (srv, (SOCKADDR *) &server, sizeof (struct sockaddr_in))) { g_print ("%d\n", WSAGetLastError ()); g_assert (1 != 0); } @@ -63,8 +57,11 @@ tp_poll_init (SocketIOData *data) len = sizeof (server); getsockname (srv, (SOCKADDR *) &server, &len); listen (srv, 1); - mono_thread_create (mono_get_root_domain (), connect_hack, &server); - len = sizeof (server); + if (connect ((SOCKET) result->pipe [1], (SOCKADDR *) &server, sizeof (server)) == SOCKET_ERROR) { + g_print ("%d\n", WSAGetLastError ()); + g_assert (1 != 0); + } + len = sizeof (client); result->pipe [0] = accept (srv, (SOCKADDR *) &client, &len); g_assert (result->pipe [0] != INVALID_SOCKET); closesocket (srv); @@ -81,15 +78,15 @@ tp_poll_modify (gpointer event_data, int fd, int operation, int events, gboolean { tp_poll_data *data = event_data; char msg [1]; - int w; + int unused; MONO_SEM_WAIT (&data->new_sem); INIT_POLLFD (&data->newpfd, GPOINTER_TO_INT (fd), events); *msg = (char) operation; #ifndef HOST_WIN32 - w = write (data->pipe [1], msg, 1); + unused = write (data->pipe [1], msg, 1); #else - send ((SOCKET) data->pipe [1], msg, 1, 0); + unused = send ((SOCKET) data->pipe [1], msg, 1, 0); #endif } @@ -145,6 +142,10 @@ tp_poll_wait (gpointer p) #define INITIAL_POLLFD_SIZE 1024 #endif #define POLL_ERRORS (MONO_POLLERR | MONO_POLLHUP | MONO_POLLNVAL) + +#ifdef DISABLE_SOCKETS +#define socket_io_cleanup(x) +#endif mono_pollfd *pfds; gint maxfd = 1; gint allocated; @@ -152,7 +153,7 @@ tp_poll_wait (gpointer p) MonoInternalThread *thread; tp_poll_data *data; SocketIOData *socket_io_data = p; - gpointer *async_results; + MonoPtrArray async_results; gint nresults; thread = mono_thread_internal_current (); @@ -160,12 +161,11 @@ tp_poll_wait (gpointer p) data = socket_io_data->event_data; allocated = INITIAL_POLLFD_SIZE; pfds = g_new0 (mono_pollfd, allocated); - async_results = g_new0 (gpointer, allocated * 2); + mono_ptr_array_init (async_results, allocated * 2); INIT_POLLFD (pfds, data->pipe [0], MONO_POLLIN); for (i = 1; i < allocated; i++) INIT_POLLFD (&pfds [i], -1, 0); - printf ("poll_wait\n"); while (1) { int nsock = 0; mono_pollfd *pfd; @@ -173,6 +173,8 @@ tp_poll_wait (gpointer p) MonoMList *list; MonoObject *ares; + mono_gc_set_skip_thread (TRUE); + do { if (nsock == -1) { if (THREAD_WANTS_A_BREAK (thread)) @@ -182,6 +184,8 @@ tp_poll_wait (gpointer p) nsock = mono_poll (pfds, maxfd, -1); } while (nsock == -1 && errno == EINTR); + mono_gc_set_skip_thread (FALSE); + /* * Apart from EINTR, we only check EBADF, for the rest: * EINVAL: mono_poll() 'protects' us from descriptor @@ -204,7 +208,7 @@ tp_poll_wait (gpointer p) if ((pfds->revents & POLL_ERRORS) != 0) { /* We're supposed to die now, as the pipe has been closed */ g_free (pfds); - g_free (async_results); + mono_ptr_array_destroy (async_results); socket_io_cleanup (socket_io_data); return; } @@ -212,11 +216,22 @@ tp_poll_wait (gpointer p) /* Got a new socket */ if ((pfds->revents & MONO_POLLIN) != 0) { int nread; + gboolean found = FALSE; for (i = 1; i < allocated; i++) { pfd = &pfds [i]; - if (pfd->fd == -1 || pfd->fd == data->newpfd.fd) + if (pfd->fd == data->newpfd.fd) { + found = TRUE; break; + } + } + + if (!found) { + for (i = 1; i < allocated; i++) { + pfd = &pfds [i]; + if (pfd->fd == -1) + break; + } } if (i == allocated) { @@ -229,7 +244,7 @@ tp_poll_wait (gpointer p) g_free (oldfd); for (; i < allocated; i++) INIT_POLLFD (&pfds [i], -1, 0); - async_results = g_renew (gpointer, async_results, allocated * 2); + //async_results = g_renew (gpointer, async_results, allocated * 2); } #ifndef HOST_WIN32 nread = read (data->pipe [0], one, 1); @@ -238,7 +253,7 @@ tp_poll_wait (gpointer p) #endif if (nread <= 0) { g_free (pfds); - g_free (async_results); + mono_ptr_array_destroy (async_results); return; /* we're closed */ } @@ -256,12 +271,14 @@ tp_poll_wait (gpointer p) EnterCriticalSection (&socket_io_data->io_lock); if (socket_io_data->inited == 3) { g_free (pfds); - g_free (async_results); + mono_ptr_array_destroy (async_results); LeaveCriticalSection (&socket_io_data->io_lock); return; /* cleanup called */ } nresults = 0; + mono_ptr_array_clear (async_results); + for (i = 1; i < maxfd && nsock > 0; i++) { pfd = &pfds [i]; if (pfd->fd == -1 || pfd->revents == 0) @@ -271,14 +288,18 @@ tp_poll_wait (gpointer p) list = mono_g_hash_table_lookup (socket_io_data->sock_to_state, GINT_TO_POINTER (pfd->fd)); if (list != NULL && (pfd->revents & (MONO_POLLIN | POLL_ERRORS)) != 0) { ares = get_io_event (&list, MONO_POLLIN); - if (ares != NULL) - async_results [nresults++] = ares; + if (ares != NULL) { + mono_ptr_array_append (async_results, ares); + ++nresults; + } } if (list != NULL && (pfd->revents & (MONO_POLLOUT | POLL_ERRORS)) != 0) { ares = get_io_event (&list, MONO_POLLOUT); - if (ares != NULL) - async_results [nresults++] = ares; + if (ares != NULL) { + mono_ptr_array_append (async_results, ares); + ++nresults; + } } if (list != NULL) { @@ -292,8 +313,8 @@ tp_poll_wait (gpointer p) } } LeaveCriticalSection (&socket_io_data->io_lock); - threadpool_append_jobs (&async_io_tp, (MonoObject **) async_results, nresults); - memset (async_results, 0, sizeof (gpointer) * nresults); + threadpool_append_jobs (&async_io_tp, (MonoObject **) async_results.data, nresults); + mono_ptr_array_clear (async_results); } }