Commit fd1dff4b418e28302018f37371dd515150f23534
1 parent
ff3fbb30
win32 socket support
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1731 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
209 additions
and
112 deletions
vl.c
... | ... | @@ -64,6 +64,8 @@ |
64 | 64 | #include <malloc.h> |
65 | 65 | #include <sys/timeb.h> |
66 | 66 | #include <windows.h> |
67 | +#include <winsock2.h> | |
68 | +#include <ws2tcpip.h> | |
67 | 69 | #define getopt_long_only getopt_long |
68 | 70 | #define memalign(align, size) malloc(size) |
69 | 71 | #endif |
... | ... | @@ -1077,20 +1079,67 @@ CharDriverState *qemu_chr_open_null(void) |
1077 | 1079 | return chr; |
1078 | 1080 | } |
1079 | 1081 | |
1080 | -#ifndef _WIN32 | |
1082 | +#ifdef _WIN32 | |
1081 | 1083 | |
1082 | -typedef struct { | |
1083 | - int fd_in, fd_out; | |
1084 | - IOCanRWHandler *fd_can_read; | |
1085 | - IOReadHandler *fd_read; | |
1086 | - void *fd_opaque; | |
1087 | - int max_size; | |
1088 | -} FDCharDriver; | |
1084 | +#define socket_error() WSAGetLastError() | |
1085 | +#undef EINTR | |
1086 | +#define EWOULDBLOCK WSAEWOULDBLOCK | |
1087 | +#define EINTR WSAEINTR | |
1088 | +#define EINPROGRESS WSAEINPROGRESS | |
1089 | 1089 | |
1090 | -#define STDIO_MAX_CLIENTS 2 | |
1090 | +static void socket_cleanup(void) | |
1091 | +{ | |
1092 | + WSACleanup(); | |
1093 | +} | |
1091 | 1094 | |
1092 | -static int stdio_nb_clients; | |
1093 | -static CharDriverState *stdio_clients[STDIO_MAX_CLIENTS]; | |
1095 | +static int socket_init(void) | |
1096 | +{ | |
1097 | + WSADATA Data; | |
1098 | + int ret, err; | |
1099 | + | |
1100 | + ret = WSAStartup(MAKEWORD(2,2), &Data); | |
1101 | + if (ret != 0) { | |
1102 | + err = WSAGetLastError(); | |
1103 | + fprintf(stderr, "WSAStartup: %d\n", err); | |
1104 | + return -1; | |
1105 | + } | |
1106 | + atexit(socket_cleanup); | |
1107 | + return 0; | |
1108 | +} | |
1109 | + | |
1110 | +static int send_all(int fd, const uint8_t *buf, int len1) | |
1111 | +{ | |
1112 | + int ret, len; | |
1113 | + | |
1114 | + len = len1; | |
1115 | + while (len > 0) { | |
1116 | + ret = send(fd, buf, len, 0); | |
1117 | + if (ret < 0) { | |
1118 | + int errno; | |
1119 | + errno = WSAGetLastError(); | |
1120 | + if (errno != WSAEWOULDBLOCK) { | |
1121 | + return -1; | |
1122 | + } | |
1123 | + } else if (ret == 0) { | |
1124 | + break; | |
1125 | + } else { | |
1126 | + buf += ret; | |
1127 | + len -= ret; | |
1128 | + } | |
1129 | + } | |
1130 | + return len1 - len; | |
1131 | +} | |
1132 | + | |
1133 | +void socket_set_nonblock(int fd) | |
1134 | +{ | |
1135 | + unsigned long opt = 1; | |
1136 | + ioctlsocket(fd, FIONBIO, &opt); | |
1137 | +} | |
1138 | + | |
1139 | +#else | |
1140 | + | |
1141 | +#define socket_error() errno | |
1142 | +#define closesocket(s) close(s) | |
1094 | 1143 | |
1095 | 1144 | static int unix_write(int fd, const uint8_t *buf, int len1) |
1096 | 1145 | { |
... | ... | @@ -1112,6 +1161,32 @@ static int unix_write(int fd, const uint8_t *buf, int len1) |
1112 | 1161 | return len1 - len; |
1113 | 1162 | } |
1114 | 1163 | |
1164 | +static inline int send_all(int fd, const uint8_t *buf, int len1) | |
1165 | +{ | |
1166 | + return unix_write(fd, buf, len1); | |
1167 | +} | |
1168 | + | |
1169 | +void socket_set_nonblock(int fd) | |
1170 | +{ | |
1171 | + fcntl(fd, F_SETFL, O_NONBLOCK); | |
1172 | +} | |
1173 | +#endif /* !_WIN32 */ | |
1174 | + | |
1175 | +#ifndef _WIN32 | |
1176 | + | |
1177 | +typedef struct { | |
1178 | + int fd_in, fd_out; | |
1179 | + IOCanRWHandler *fd_can_read; | |
1180 | + IOReadHandler *fd_read; | |
1181 | + void *fd_opaque; | |
1182 | + int max_size; | |
1183 | +} FDCharDriver; | |
1184 | + | |
1185 | +#define STDIO_MAX_CLIENTS 2 | |
1186 | + | |
1187 | +static int stdio_nb_clients; | |
1188 | +static CharDriverState *stdio_clients[STDIO_MAX_CLIENTS]; | |
1189 | + | |
1115 | 1190 | static int fd_chr_write(CharDriverState *chr, const uint8_t *buf, int len) |
1116 | 1191 | { |
1117 | 1192 | FDCharDriver *s = chr->opaque; |
... | ... | @@ -1617,7 +1692,10 @@ CharDriverState *qemu_chr_open_pty(void) |
1617 | 1692 | |
1618 | 1693 | CharDriverState *qemu_chr_open(const char *filename) |
1619 | 1694 | { |
1695 | +#ifndef _WIN32 | |
1620 | 1696 | const char *p; |
1697 | +#endif | |
1698 | + | |
1621 | 1699 | if (!strcmp(filename, "vc")) { |
1622 | 1700 | return text_console_init(&display_state); |
1623 | 1701 | } else if (!strcmp(filename, "null")) { |
... | ... | @@ -1731,13 +1809,9 @@ int parse_host_port(struct sockaddr_in *saddr, const char *str) |
1731 | 1809 | if (!inet_aton(buf, &saddr->sin_addr)) |
1732 | 1810 | return -1; |
1733 | 1811 | } else { |
1734 | -#ifdef _WIN32 | |
1735 | - return -1; | |
1736 | -#else | |
1737 | 1812 | if ((he = gethostbyname(buf)) == NULL) |
1738 | 1813 | return - 1; |
1739 | 1814 | saddr->sin_addr = *(struct in_addr *)he->h_addr; |
1740 | -#endif | |
1741 | 1815 | } |
1742 | 1816 | } |
1743 | 1817 | port = strtol(p, (char **)&r, 0); |
... | ... | @@ -2127,6 +2201,8 @@ static int net_tap_init(VLANState *vlan, const char *ifname1, |
2127 | 2201 | return 0; |
2128 | 2202 | } |
2129 | 2203 | |
2204 | +#endif /* !_WIN32 */ | |
2205 | + | |
2130 | 2206 | /* network connection */ |
2131 | 2207 | typedef struct NetSocketState { |
2132 | 2208 | VLANClientState *vc; |
... | ... | @@ -2150,8 +2226,8 @@ static void net_socket_receive(void *opaque, const uint8_t *buf, int size) |
2150 | 2226 | uint32_t len; |
2151 | 2227 | len = htonl(size); |
2152 | 2228 | |
2153 | - unix_write(s->fd, (const uint8_t *)&len, sizeof(len)); | |
2154 | - unix_write(s->fd, buf, size); | |
2229 | + send_all(s->fd, (const uint8_t *)&len, sizeof(len)); | |
2230 | + send_all(s->fd, buf, size); | |
2155 | 2231 | } |
2156 | 2232 | |
2157 | 2233 | static void net_socket_receive_dgram(void *opaque, const uint8_t *buf, int size) |
... | ... | @@ -2164,16 +2240,20 @@ static void net_socket_receive_dgram(void *opaque, const uint8_t *buf, int size) |
2164 | 2240 | static void net_socket_send(void *opaque) |
2165 | 2241 | { |
2166 | 2242 | NetSocketState *s = opaque; |
2167 | - int l, size; | |
2243 | + int l, size, err; | |
2168 | 2244 | uint8_t buf1[4096]; |
2169 | 2245 | const uint8_t *buf; |
2170 | 2246 | |
2171 | - size = read(s->fd, buf1, sizeof(buf1)); | |
2172 | - if (size < 0) | |
2173 | - return; | |
2174 | - if (size == 0) { | |
2247 | + size = recv(s->fd, buf1, sizeof(buf1), 0); | |
2248 | + if (size < 0) { | |
2249 | + err = socket_error(); | |
2250 | + if (err != EWOULDBLOCK) | |
2251 | + goto eoc; | |
2252 | + } else if (size == 0) { | |
2175 | 2253 | /* end of connection */ |
2254 | + eoc: | |
2176 | 2255 | qemu_set_fd_handler(s->fd, NULL, NULL, NULL); |
2256 | + closesocket(s->fd); | |
2177 | 2257 | return; |
2178 | 2258 | } |
2179 | 2259 | buf = buf1; |
... | ... | @@ -2236,7 +2316,8 @@ static int net_socket_mcast_create(struct sockaddr_in *mcastaddr) |
2236 | 2316 | int val, ret; |
2237 | 2317 | if (!IN_MULTICAST(ntohl(mcastaddr->sin_addr.s_addr))) { |
2238 | 2318 | fprintf(stderr, "qemu: error: specified mcastaddr \"%s\" (0x%08x) does not contain a multicast address\n", |
2239 | - inet_ntoa(mcastaddr->sin_addr), ntohl(mcastaddr->sin_addr.s_addr)); | |
2319 | + inet_ntoa(mcastaddr->sin_addr), | |
2320 | + (int)ntohl(mcastaddr->sin_addr.s_addr)); | |
2240 | 2321 | return -1; |
2241 | 2322 | |
2242 | 2323 | } |
... | ... | @@ -2246,11 +2327,26 @@ static int net_socket_mcast_create(struct sockaddr_in *mcastaddr) |
2246 | 2327 | return -1; |
2247 | 2328 | } |
2248 | 2329 | |
2330 | + val = 1; | |
2331 | + ret=setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, | |
2332 | + (const char *)&val, sizeof(val)); | |
2333 | + if (ret < 0) { | |
2334 | + perror("setsockopt(SOL_SOCKET, SO_REUSEADDR)"); | |
2335 | + goto fail; | |
2336 | + } | |
2337 | + | |
2338 | + ret = bind(fd, (struct sockaddr *)mcastaddr, sizeof(*mcastaddr)); | |
2339 | + if (ret < 0) { | |
2340 | + perror("bind"); | |
2341 | + goto fail; | |
2342 | + } | |
2343 | + | |
2249 | 2344 | /* Add host to multicast group */ |
2250 | 2345 | imr.imr_multiaddr = mcastaddr->sin_addr; |
2251 | 2346 | imr.imr_interface.s_addr = htonl(INADDR_ANY); |
2252 | 2347 | |
2253 | - ret = setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (void *) &imr, sizeof(struct ip_mreq)); | |
2348 | + ret = setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, | |
2349 | + (const char *)&imr, sizeof(struct ip_mreq)); | |
2254 | 2350 | if (ret < 0) { |
2255 | 2351 | perror("setsockopt(IP_ADD_MEMBERSHIP)"); |
2256 | 2352 | goto fail; |
... | ... | @@ -2258,25 +2354,14 @@ static int net_socket_mcast_create(struct sockaddr_in *mcastaddr) |
2258 | 2354 | |
2259 | 2355 | /* Force mcast msgs to loopback (eg. several QEMUs in same host */ |
2260 | 2356 | val = 1; |
2261 | - ret=setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, &val, sizeof(val)); | |
2357 | + ret=setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, | |
2358 | + (const char *)&val, sizeof(val)); | |
2262 | 2359 | if (ret < 0) { |
2263 | 2360 | perror("setsockopt(SOL_IP, IP_MULTICAST_LOOP)"); |
2264 | 2361 | goto fail; |
2265 | 2362 | } |
2266 | 2363 | |
2267 | - ret=setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)); | |
2268 | - if (ret < 0) { | |
2269 | - perror("setsockopt(SOL_SOCKET, SO_REUSEADDR)"); | |
2270 | - goto fail; | |
2271 | - } | |
2272 | - | |
2273 | - ret = bind(fd, (struct sockaddr *)mcastaddr, sizeof(*mcastaddr)); | |
2274 | - if (ret < 0) { | |
2275 | - perror("bind"); | |
2276 | - goto fail; | |
2277 | - } | |
2278 | - | |
2279 | - fcntl(fd, F_SETFL, O_NONBLOCK); | |
2364 | + socket_set_nonblock(fd); | |
2280 | 2365 | return fd; |
2281 | 2366 | fail: |
2282 | 2367 | if (fd>=0) close(fd); |
... | ... | @@ -2371,7 +2456,7 @@ static NetSocketState *net_socket_fd_init(VLANState *vlan, int fd, |
2371 | 2456 | { |
2372 | 2457 | int so_type=-1, optlen=sizeof(so_type); |
2373 | 2458 | |
2374 | - if(getsockopt(fd, SOL_SOCKET,SO_TYPE, &so_type, &optlen)< 0) { | |
2459 | + if(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&so_type, &optlen)< 0) { | |
2375 | 2460 | fprintf(stderr, "qemu: error: setsockopt(SO_TYPE) for fd=%d failed\n", fd); |
2376 | 2461 | return NULL; |
2377 | 2462 | } |
... | ... | @@ -2433,11 +2518,11 @@ static int net_socket_listen_init(VLANState *vlan, const char *host_str) |
2433 | 2518 | perror("socket"); |
2434 | 2519 | return -1; |
2435 | 2520 | } |
2436 | - fcntl(fd, F_SETFL, O_NONBLOCK); | |
2521 | + socket_set_nonblock(fd); | |
2437 | 2522 | |
2438 | 2523 | /* allow fast reuse */ |
2439 | 2524 | val = 1; |
2440 | - setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)); | |
2525 | + setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char *)&val, sizeof(val)); | |
2441 | 2526 | |
2442 | 2527 | ret = bind(fd, (struct sockaddr *)&saddr, sizeof(saddr)); |
2443 | 2528 | if (ret < 0) { |
... | ... | @@ -2458,7 +2543,7 @@ static int net_socket_listen_init(VLANState *vlan, const char *host_str) |
2458 | 2543 | static int net_socket_connect_init(VLANState *vlan, const char *host_str) |
2459 | 2544 | { |
2460 | 2545 | NetSocketState *s; |
2461 | - int fd, connected, ret; | |
2546 | + int fd, connected, ret, err; | |
2462 | 2547 | struct sockaddr_in saddr; |
2463 | 2548 | |
2464 | 2549 | if (parse_host_port(&saddr, host_str) < 0) |
... | ... | @@ -2469,18 +2554,19 @@ static int net_socket_connect_init(VLANState *vlan, const char *host_str) |
2469 | 2554 | perror("socket"); |
2470 | 2555 | return -1; |
2471 | 2556 | } |
2472 | - fcntl(fd, F_SETFL, O_NONBLOCK); | |
2557 | + socket_set_nonblock(fd); | |
2473 | 2558 | |
2474 | 2559 | connected = 0; |
2475 | 2560 | for(;;) { |
2476 | 2561 | ret = connect(fd, (struct sockaddr *)&saddr, sizeof(saddr)); |
2477 | 2562 | if (ret < 0) { |
2478 | - if (errno == EINTR || errno == EAGAIN) { | |
2479 | - } else if (errno == EINPROGRESS) { | |
2563 | + err = socket_error(); | |
2564 | + if (err == EINTR || err == EWOULDBLOCK) { | |
2565 | + } else if (err == EINPROGRESS) { | |
2480 | 2566 | break; |
2481 | 2567 | } else { |
2482 | 2568 | perror("connect"); |
2483 | - close(fd); | |
2569 | + closesocket(fd); | |
2484 | 2570 | return -1; |
2485 | 2571 | } |
2486 | 2572 | } else { |
... | ... | @@ -2524,8 +2610,6 @@ static int net_socket_mcast_init(VLANState *vlan, const char *host_str) |
2524 | 2610 | |
2525 | 2611 | } |
2526 | 2612 | |
2527 | -#endif /* !_WIN32 */ | |
2528 | - | |
2529 | 2613 | static int get_param_value(char *buf, int buf_size, |
2530 | 2614 | const char *tag, const char *str) |
2531 | 2615 | { |
... | ... | @@ -2649,6 +2733,7 @@ int net_client_init(const char *str) |
2649 | 2733 | ret = net_tap_init(vlan, ifname, setup_script); |
2650 | 2734 | } |
2651 | 2735 | } else |
2736 | +#endif | |
2652 | 2737 | if (!strcmp(device, "socket")) { |
2653 | 2738 | if (get_param_value(buf, sizeof(buf), "fd", p) > 0) { |
2654 | 2739 | int fd; |
... | ... | @@ -2667,7 +2752,6 @@ int net_client_init(const char *str) |
2667 | 2752 | return -1; |
2668 | 2753 | } |
2669 | 2754 | } else |
2670 | -#endif | |
2671 | 2755 | { |
2672 | 2756 | fprintf(stderr, "Unknown network device: %s\n", device); |
2673 | 2757 | return -1; |
... | ... | @@ -2918,6 +3002,7 @@ int qemu_set_fd_handler2(int fd, |
2918 | 3002 | break; |
2919 | 3003 | if (ioh->fd == fd) { |
2920 | 3004 | *pioh = ioh->next; |
3005 | + qemu_free(ioh); | |
2921 | 3006 | break; |
2922 | 3007 | } |
2923 | 3008 | pioh = &ioh->next; |
... | ... | @@ -3812,80 +3897,88 @@ void qemu_system_powerdown_request(void) |
3812 | 3897 | |
3813 | 3898 | void main_loop_wait(int timeout) |
3814 | 3899 | { |
3815 | -#ifndef _WIN32 | |
3816 | - struct pollfd ufds[MAX_IO_HANDLERS + 1], *pf; | |
3817 | 3900 | IOHandlerRecord *ioh, *ioh_next; |
3818 | -#endif | |
3819 | - int ret; | |
3901 | + fd_set rfds, wfds; | |
3902 | + int ret, nfds; | |
3903 | + struct timeval tv; | |
3820 | 3904 | |
3821 | 3905 | #ifdef _WIN32 |
3822 | - if (timeout > 0) | |
3823 | - Sleep(timeout); | |
3906 | + /* XXX: see how to merge it with the select. The constraint is | |
3907 | + that the select must be interrupted by the timer */ | |
3908 | + if (timeout > 0) | |
3909 | + Sleep(timeout); | |
3910 | +#endif | |
3911 | + /* poll any events */ | |
3912 | + /* XXX: separate device handlers from system ones */ | |
3913 | + nfds = -1; | |
3914 | + FD_ZERO(&rfds); | |
3915 | + FD_ZERO(&wfds); | |
3916 | + for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) { | |
3917 | + if (ioh->fd_read && | |
3918 | + (!ioh->fd_read_poll || | |
3919 | + ioh->fd_read_poll(ioh->opaque) != 0)) { | |
3920 | + FD_SET(ioh->fd, &rfds); | |
3921 | + if (ioh->fd > nfds) | |
3922 | + nfds = ioh->fd; | |
3923 | + } | |
3924 | + if (ioh->fd_write) { | |
3925 | + FD_SET(ioh->fd, &wfds); | |
3926 | + if (ioh->fd > nfds) | |
3927 | + nfds = ioh->fd; | |
3928 | + } | |
3929 | + } | |
3930 | + | |
3931 | + tv.tv_sec = 0; | |
3932 | +#ifdef _WIN32 | |
3933 | + tv.tv_usec = 0; | |
3824 | 3934 | #else |
3825 | - /* poll any events */ | |
3826 | - /* XXX: separate device handlers from system ones */ | |
3827 | - pf = ufds; | |
3828 | - for(ioh = first_io_handler; ioh != NULL; ioh = ioh->next) { | |
3829 | - pf->events = 0; | |
3830 | - pf->fd = ioh->fd; | |
3831 | - if (ioh->fd_read && | |
3832 | - (!ioh->fd_read_poll || | |
3833 | - ioh->fd_read_poll(ioh->opaque) != 0)) { | |
3834 | - pf->events |= POLLIN; | |
3935 | + tv.tv_usec = timeout * 1000; | |
3936 | +#endif | |
3937 | + ret = select(nfds + 1, &rfds, &wfds, NULL, &tv); | |
3938 | + if (ret > 0) { | |
3939 | + /* XXX: better handling of removal */ | |
3940 | + for(ioh = first_io_handler; ioh != NULL; ioh = ioh_next) { | |
3941 | + ioh_next = ioh->next; | |
3942 | + if (FD_ISSET(ioh->fd, &rfds)) { | |
3943 | + ioh->fd_read(ioh->opaque); | |
3835 | 3944 | } |
3836 | - if (ioh->fd_write) { | |
3837 | - pf->events |= POLLOUT; | |
3945 | + if (FD_ISSET(ioh->fd, &wfds)) { | |
3946 | + ioh->fd_write(ioh->opaque); | |
3838 | 3947 | } |
3839 | - ioh->ufd = pf; | |
3840 | - pf++; | |
3841 | 3948 | } |
3842 | - | |
3843 | - ret = poll(ufds, pf - ufds, timeout); | |
3844 | - if (ret > 0) { | |
3845 | - /* XXX: better handling of removal */ | |
3846 | - for(ioh = first_io_handler; ioh != NULL; ioh = ioh_next) { | |
3847 | - ioh_next = ioh->next; | |
3848 | - pf = ioh->ufd; | |
3849 | - if (pf->revents & POLLIN) { | |
3850 | - ioh->fd_read(ioh->opaque); | |
3851 | - } | |
3852 | - if (pf->revents & POLLOUT) { | |
3853 | - ioh->fd_write(ioh->opaque); | |
3854 | - } | |
3855 | - } | |
3856 | - } | |
3857 | -#endif /* !defined(_WIN32) */ | |
3949 | + } | |
3950 | + | |
3858 | 3951 | #if defined(CONFIG_SLIRP) |
3859 | - /* XXX: merge with poll() */ | |
3860 | - if (slirp_inited) { | |
3861 | - fd_set rfds, wfds, xfds; | |
3862 | - int nfds; | |
3863 | - struct timeval tv; | |
3864 | - | |
3865 | - nfds = -1; | |
3866 | - FD_ZERO(&rfds); | |
3867 | - FD_ZERO(&wfds); | |
3868 | - FD_ZERO(&xfds); | |
3869 | - slirp_select_fill(&nfds, &rfds, &wfds, &xfds); | |
3870 | - tv.tv_sec = 0; | |
3871 | - tv.tv_usec = 0; | |
3872 | - ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv); | |
3873 | - if (ret >= 0) { | |
3874 | - slirp_select_poll(&rfds, &wfds, &xfds); | |
3875 | - } | |
3952 | + /* XXX: merge with the previous select() */ | |
3953 | + if (slirp_inited) { | |
3954 | + fd_set rfds, wfds, xfds; | |
3955 | + int nfds; | |
3956 | + struct timeval tv; | |
3957 | + | |
3958 | + nfds = -1; | |
3959 | + FD_ZERO(&rfds); | |
3960 | + FD_ZERO(&wfds); | |
3961 | + FD_ZERO(&xfds); | |
3962 | + slirp_select_fill(&nfds, &rfds, &wfds, &xfds); | |
3963 | + tv.tv_sec = 0; | |
3964 | + tv.tv_usec = 0; | |
3965 | + ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv); | |
3966 | + if (ret >= 0) { | |
3967 | + slirp_select_poll(&rfds, &wfds, &xfds); | |
3876 | 3968 | } |
3969 | + } | |
3877 | 3970 | #endif |
3878 | 3971 | |
3879 | - if (vm_running) { | |
3880 | - qemu_run_timers(&active_timers[QEMU_TIMER_VIRTUAL], | |
3881 | - qemu_get_clock(vm_clock)); | |
3882 | - /* run dma transfers, if any */ | |
3883 | - DMA_run(); | |
3884 | - } | |
3885 | - | |
3886 | - /* real time timers */ | |
3887 | - qemu_run_timers(&active_timers[QEMU_TIMER_REALTIME], | |
3888 | - qemu_get_clock(rt_clock)); | |
3972 | + if (vm_running) { | |
3973 | + qemu_run_timers(&active_timers[QEMU_TIMER_VIRTUAL], | |
3974 | + qemu_get_clock(vm_clock)); | |
3975 | + /* run dma transfers, if any */ | |
3976 | + DMA_run(); | |
3977 | + } | |
3978 | + | |
3979 | + /* real time timers */ | |
3980 | + qemu_run_timers(&active_timers[QEMU_TIMER_REALTIME], | |
3981 | + qemu_get_clock(rt_clock)); | |
3889 | 3982 | } |
3890 | 3983 | |
3891 | 3984 | static CPUState *cur_cpu; |
... | ... | @@ -4807,6 +4900,10 @@ int main(int argc, char **argv) |
4807 | 4900 | setvbuf(stdout, NULL, _IOLBF, 0); |
4808 | 4901 | #endif |
4809 | 4902 | |
4903 | +#ifdef _WIN32 | |
4904 | + socket_init(); | |
4905 | +#endif | |
4906 | + | |
4810 | 4907 | /* init network clients */ |
4811 | 4908 | if (nb_net_clients == 0) { |
4812 | 4909 | /* if no clients, we use a default config */ | ... | ... |