... int sockfd; fd_set fdR; struct timeval timeout = ..; ... for(;;) { FD_ZERO(&fdR); FD_SET(sockfd, &fdR); switch (select(sockfd + 1, &fdR, NULL, &timeout)) { case -1: error handled by u; case 0: timeout hanled by u; default: if (FD_ISSET(sockfd)) { now u read or recv something; /* if sockfd is father and server socket, u can now accept() */ } } }
DBUG_PRINT("general",("Waiting for connections.")); MAYBE_BROKEN_SYSCALL; while (!abort_loop) { readFDs=clientFDs; #ifdef HPUX10 if (select(max_used_connection,(int*) &readFDs,0,0,0) < 0) continue; #else if (select((int) max_used_connection,&readFDs,0,0,0) < 0) { if (socket_errno != SOCKET_EINTR) { if (!select_errors++ && !abort_loop) /* purecov: inspected */ sql_print_error("mysqld: Got error %d from select",socket_errno); /* purecov: inspected */ } MAYBE_BROKEN_SYSCALL continue; } #endif /* HPUX10 */ if (abort_loop) { MAYBE_BROKEN_SYSCALL; break; }
/* Is this a new connection request ? */ #ifdef HAVE_SYS_UN_H if (FD_ISSET(unix_sock,&readFDs)) { sock = unix_sock; flags= socket_flags; } else #endif { sock = ip_sock; flags= ip_flags; }
#if !defined(NO_FCNTL_NONBLOCK) if (!(test_flags & TEST_BLOCKING)) { #if defined(O_NONBLOCK) fcntl(sock, F_SETFL, flags | O_NONBLOCK); #elif defined(O_NDELAY) fcntl(sock, F_SETFL, flags | O_NDELAY); #endif } #endif /* NO_FCNTL_NONBLOCK */ for (uint retry=0; retry < MAX_ACCEPT_RETRY; retry++) { size_socket length=sizeof(struct sockaddr_in); new_sock = accept(sock, my_reinterpret_cast(struct sockaddr *) (&cAddr), &length); #ifdef __NETWARE__ // TODO: temporary fix, waiting for TCP/IP fix - DEFECT000303149 if ((new_sock == INVALID_SOCKET) && (socket_errno == EINVAL)) { kill_server(SIGTERM); } #endif if (new_sock != INVALID_SOCKET || (socket_errno != SOCKET_EINTR && socket_errno != SOCKET_EAGAIN)) break; MAYBE_BROKEN_SYSCALL; #if !defined(NO_FCNTL_NONBLOCK) if (!(test_flags & TEST_BLOCKING)) { if (retry == MAX_ACCEPT_RETRY - 1) fcntl(sock, F_SETFL, flags); // Try without O_NONBLOCK } #endif } #if !defined(NO_FCNTL_NONBLOCK) if (!(test_flags & TEST_BLOCKING)) fcntl(sock, F_SETFL, flags); #endif if (new_sock == INVALID_SOCKET) { if ((error_count++ & 255) == 0) // This can happen often sql_perror("Error in accept"); MAYBE_BROKEN_SYSCALL; if (socket_errno == SOCKET_ENFILE || socket_errno == SOCKET_EMFILE) sleep(1); // Give other threads some time continue; }
#ifdef HAVE_LIBWRAP { if (sock == ip_sock) { struct request_info req; signal(SIGCHLD, SIG_DFL); request_init(&req, RQ_DAEMON, libwrapName, RQ_FILE, new_sock, NULL); fromhost(&req); if (!hosts_access(&req)) { /* This may be stupid but refuse() includes an exit(0) which we surely don't want... clean_exit() - same stupid thing ... */ syslog(deny_severity, "refused connect from %s", eval_client(&req));
/* C++ sucks (the gibberish in front just translates the supplied sink function pointer in the req structure from a void (*sink)(); to a void(*sink)(int) if you omit the cast, the C++ compiler will cry... */ if (req.sink) ((void (*)(int))req.sink)(req.fd);
if (my_security_attr_create(&sa_event, &errmsg, GENERIC_ALL, SYNCHRONIZE | EVENT_MODIFY_STATE)) goto error;
if (my_security_attr_create(&sa_mapping, &errmsg, GENERIC_ALL, FILE_MAP_READ | FILE_MAP_WRITE)) goto error;
/* The name of event and file-mapping events create agree next rule: shared_memory_base_name+unique_part Where: shared_memory_base_name is unique value for each server unique_part is unique value for each object (events and file-mapping) */ suffix_pos= strxmov(tmp,shared_memory_base_name,"_",NullS); strmov(suffix_pos, "CONNECT_REQUEST"); if ((smem_event_connect_request= CreateEvent(sa_event, FALSE, FALSE, tmp)) == 0) { errmsg= "Could not create request event"; goto error; } strmov(suffix_pos, "CONNECT_ANSWER"); if ((event_connect_answer= CreateEvent(sa_event, FALSE, FALSE, tmp)) == 0) { errmsg="Could not create answer event"; goto error; } strmov(suffix_pos, "CONNECT_DATA"); if ((handle_connect_file_map= CreateFileMapping(INVALID_HANDLE_VALUE, sa_mapping, PAGE_READWRITE, 0, sizeof(connect_number), tmp)) == 0) { errmsg= "Could not create file mapping"; goto error; } if ((handle_connect_map= (char *)MapViewOfFile(handle_connect_file_map, FILE_MAP_WRITE,0,0, sizeof(DWORD))) == 0) { errmsg= "Could not create shared memory service"; goto error; }
while (!abort_loop) { /* Wait a request from client */ WaitForSingleObject(smem_event_connect_request,INFINITE);
/* it can be after shutdown command */ if (abort_loop) goto error;
HANDLE handle_client_file_map= 0; char *handle_client_map= 0; HANDLE event_client_wrote= 0; HANDLE event_client_read= 0; // for transfer data server <-> client HANDLE event_server_wrote= 0; HANDLE event_server_read= 0; HANDLE event_conn_closed= 0; THD *thd= 0;
p= int10_to_str(connect_number, connect_number_char, 10); /* The name of event and file-mapping events create agree next rule: shared_memory_base_name+unique_part+number_of_connection Where: shared_memory_base_name is uniquel value for each server unique_part is unique value for each object (events and file-mapping) number_of_connection is connection-number between server and client */ suffix_pos= strxmov(tmp,shared_memory_base_name,"_",connect_number_char, "_",NullS); strmov(suffix_pos, "DATA"); if ((handle_client_file_map= CreateFileMapping(INVALID_HANDLE_VALUE, sa_mapping, PAGE_READWRITE, 0, smem_buffer_length, tmp)) == 0) { errmsg= "Could not create file mapping"; goto errorconn; } if ((handle_client_map= (char*)MapViewOfFile(handle_client_file_map, FILE_MAP_WRITE,0,0, smem_buffer_length)) == 0) { errmsg= "Could not create memory map"; goto errorconn; } strmov(suffix_pos, "CLIENT_WROTE"); if ((event_client_wrote= CreateEvent(sa_event, FALSE, FALSE, tmp)) == 0) { errmsg= "Could not create client write event"; goto errorconn; } strmov(suffix_pos, "CLIENT_READ"); if ((event_client_read= CreateEvent(sa_event, FALSE, FALSE, tmp)) == 0) { errmsg= "Could not create client read event"; goto errorconn; } strmov(suffix_pos, "SERVER_READ"); if ((event_server_read= CreateEvent(sa_event, FALSE, FALSE, tmp)) == 0) { errmsg= "Could not create server read event"; goto errorconn; } strmov(suffix_pos, "SERVER_WROTE"); if ((event_server_wrote= CreateEvent(sa_event, FALSE, FALSE, tmp)) == 0) { errmsg= "Could not create server write event"; goto errorconn; } strmov(suffix_pos, "CONNECTION_CLOSED"); if ((event_conn_closed= CreateEvent(sa_event, TRUE, FALSE, tmp)) == 0) { errmsg= "Could not create closed connection event"; goto errorconn; } if (abort_loop) goto errorconn; if (!(thd= new THD)) goto errorconn; /* Send number of connection to client */ int4store(handle_connect_map, connect_number); if (!SetEvent(event_connect_answer)) { errmsg= "Could not send answer event"; goto errorconn; } /* Set event that client should receive data */ if (!SetEvent(event_client_read)) { errmsg= "Could not set client to read mode"; goto errorconn; } if (!(thd->net.vio= vio_new_win32shared_memory(&thd->net, handle_client_file_map, handle_client_map, event_client_wrote, event_client_read, event_server_wrote, event_server_read, event_conn_closed)) || my_net_init(&thd->net, thd->net.vio)) { close_connection(thd, ER_OUT_OF_RESOURCES, 1); errmsg= 0; goto errorconn; } thd->host= my_strdup(my_localhost,MYF(0)); /* Host is unknown */ create_new_thread(thd); connect_number++; continue;
errorconn: /* Could not form connection; Free used handlers/memort and retry */ if (errmsg) { char buff[180]; strxmov(buff, "Can't create shared memory connection: ", errmsg, ".", NullS); sql_perror(buff); } if (handle_client_file_map) CloseHandle(handle_client_file_map); if (handle_client_map) UnmapViewOfFile(handle_client_map); if (event_server_wrote) CloseHandle(event_server_wrote); if (event_server_read) CloseHandle(event_server_read); if (event_client_wrote) CloseHandle(event_client_wrote); if (event_client_read) CloseHandle(event_client_read); if (event_conn_closed) CloseHandle(event_conn_closed); delete thd; }
/* End shared memory handling */ error: if (errmsg) { char buff[180]; strxmov(buff, "Can't create shared memory service: ", errmsg, ".", NullS); sql_perror(buff); } my_security_attr_free(sa_event); my_security_attr_free(sa_mapping); if (handle_connect_map) UnmapViewOfFile(handle_connect_map); if (handle_connect_file_map) CloseHandle(handle_connect_file_map); if (event_connect_answer) CloseHandle(event_connect_answer); if (smem_event_connect_request) CloseHandle(smem_event_connect_request);