| 551 if (!(MyWSANSPIoctl = (void*) wpurple_find_and_loadproc("ws2_32.dll", "WSANSPIoctl"))) { |
556 if (!(MyWSANSPIoctl = (void*) wpurple_find_and_loadproc("ws2_32.dll", "WSANSPIoctl"))) { |
| 552 g_thread_exit(NULL); |
557 g_thread_exit(NULL); |
| 553 return NULL; |
558 return NULL; |
| 554 } |
559 } |
| 555 |
560 |
| |
561 if ((nla_event = WSACreateEvent()) == WSA_INVALID_EVENT) { |
| |
562 int errorid = WSAGetLastError(); |
| |
563 gchar *msg = g_win32_error_message(errorid); |
| |
564 purple_debug_warning("network", "Couldn't create WSA event. " |
| |
565 "Message: %s (%d).\n", msg, errorid); |
| |
566 g_free(msg); |
| |
567 g_thread_exit(NULL); |
| |
568 return NULL; |
| |
569 } |
| |
570 |
| 556 while (TRUE) { |
571 while (TRUE) { |
| 557 int retval; |
572 int retval; |
| 558 DWORD retLen = 0; |
573 DWORD retLen = 0; |
| |
574 WSACOMPLETION completion; |
| |
575 WSAOVERLAPPED overlapped; |
| |
576 |
| |
577 g_static_mutex_lock(&mutex); |
| |
578 if (network_initialized == FALSE) { |
| |
579 /* purple_network_uninit has been called */ |
| |
580 WSACloseEvent(nla_event); |
| |
581 g_static_mutex_unlock(&mutex); |
| |
582 g_thread_exit(NULL); |
| |
583 return NULL; |
| |
584 } |
| 559 |
585 |
| 560 memset(&qs, 0, sizeof(WSAQUERYSET)); |
586 memset(&qs, 0, sizeof(WSAQUERYSET)); |
| 561 qs.dwSize = sizeof(WSAQUERYSET); |
587 qs.dwSize = sizeof(WSAQUERYSET); |
| 562 qs.dwNameSpace = NS_NLA; |
588 qs.dwNameSpace = NS_NLA; |
| 563 if (WSALookupServiceBegin(&qs, 0, &h) == SOCKET_ERROR) { |
589 if (WSALookupServiceBegin(&qs, 0, &network_change_handle) == SOCKET_ERROR) { |
| 564 int errorid = WSAGetLastError(); |
590 int errorid = WSAGetLastError(); |
| 565 gchar *msg = g_win32_error_message(errorid); |
591 gchar *msg = g_win32_error_message(errorid); |
| 566 purple_debug_warning("network", "Couldn't retrieve NLA SP lookup handle. " |
592 purple_debug_warning("network", "Couldn't retrieve NLA SP lookup handle. " |
| 567 "NLA service is probably not running. Message: %s (%d).\n", |
593 "NLA service is probably not running. Message: %s (%d).\n", |
| 568 msg, errorid); |
594 msg, errorid); |
| 569 g_free(msg); |
595 g_free(msg); |
| |
596 WSACloseEvent(nla_event); |
| |
597 g_static_mutex_unlock(&mutex); |
| 570 g_thread_exit(NULL); |
598 g_thread_exit(NULL); |
| 571 return NULL; |
599 return NULL; |
| 572 } |
600 } |
| |
601 g_static_mutex_unlock(&mutex); |
| 573 |
602 |
| 574 /* Make sure at least 30 seconds have elapsed since the last |
603 /* Make sure at least 30 seconds have elapsed since the last |
| 575 * notification so we don't peg the cpu if this keeps changing. */ |
604 * notification so we don't peg the cpu if this keeps changing. */ |
| 576 if ((time(NULL) - last_trigger) < 30) |
605 if ((time(NULL) - last_trigger) < 30) |
| 577 Sleep(30000); |
606 Sleep(30000); |
| 578 |
607 |
| 579 last_trigger = time(NULL); |
608 last_trigger = time(NULL); |
| 580 |
609 |
| 581 /* This will block until there is a network change */ |
610 memset(&completion, 0, sizeof(WSACOMPLETION)); |
| 582 if (MyWSANSPIoctl(h, SIO_NSP_NOTIFY_CHANGE, NULL, 0, NULL, 0, &retLen, NULL) == SOCKET_ERROR) { |
611 completion.Type = NSP_NOTIFY_EVENT; |
| |
612 overlapped.hEvent = nla_event; |
| |
613 completion.Parameters.Event.lpOverlapped = &overlapped; |
| |
614 |
| |
615 if (MyWSANSPIoctl(network_change_handle, SIO_NSP_NOTIFY_CHANGE, NULL, 0, NULL, 0, &retLen, &completion) == SOCKET_ERROR) { |
| 583 int errorid = WSAGetLastError(); |
616 int errorid = WSAGetLastError(); |
| 584 gchar *msg = g_win32_error_message(errorid); |
617 /* WSA_IO_PENDING indicates successful async notification will happen */ |
| 585 purple_debug_warning("network", "Unable to wait for changes. Message: %s (%d).\n", |
618 if (errorid != WSA_IO_PENDING) { |
| 586 msg, errorid); |
619 gchar *msg = g_win32_error_message(errorid); |
| 587 g_free(msg); |
620 purple_debug_warning("network", "Unable to wait for changes. Message: %s (%d).\n", |
| 588 } |
621 msg, errorid); |
| 589 |
622 g_free(msg); |
| 590 retval = WSALookupServiceEnd(h); |
623 } |
| |
624 } |
| |
625 |
| |
626 /* This will block until NLA notifies us */ |
| |
627 retval = WaitForSingleObjectEx(nla_event, WSA_INFINITE, TRUE); |
| |
628 |
| |
629 g_static_mutex_lock(&mutex); |
| |
630 if (network_initialized == FALSE) { |
| |
631 /* Time to die */ |
| |
632 WSACloseEvent(nla_event); |
| |
633 g_static_mutex_unlock(&mutex); |
| |
634 g_thread_exit(NULL); |
| |
635 return NULL; |
| |
636 } |
| |
637 |
| |
638 retval = WSALookupServiceEnd(network_change_handle); |
| |
639 network_change_handle = NULL; |
| |
640 WSAResetEvent(nla_event); |
| |
641 g_static_mutex_unlock(&mutex); |
| 591 |
642 |
| 592 purple_timeout_add(0, wpurple_network_change_thread_cb, NULL); |
643 purple_timeout_add(0, wpurple_network_change_thread_cb, NULL); |
| 593 |
|
| 594 } |
644 } |
| 595 |
645 |
| 596 g_thread_exit(NULL); |
646 g_thread_exit(NULL); |
| 597 return NULL; |
647 return NULL; |
| 598 } |
648 } |
| 795 } |
846 } |
| 796 if (nm_conn) |
847 if (nm_conn) |
| 797 dbus_g_connection_unref(nm_conn); |
848 dbus_g_connection_unref(nm_conn); |
| 798 #endif |
849 #endif |
| 799 |
850 |
| |
851 #ifdef _WIN32 |
| |
852 g_static_mutex_lock(&mutex); |
| |
853 network_initialized = FALSE; |
| |
854 if (network_change_handle != NULL) { |
| |
855 int retval; |
| |
856 /* Trigger the NLA thread to stop waiting for network changes. Not |
| |
857 * doing this can cause hangs on WSACleanup. */ |
| |
858 purple_debug_warning("network", "Terminating the NLA thread\n"); |
| |
859 if ((retval = WSALookupServiceEnd(network_change_handle)) == SOCKET_ERROR) { |
| |
860 int errorid = WSAGetLastError(); |
| |
861 gchar *msg = g_win32_error_message(errorid); |
| |
862 purple_debug_warning("network", "Unable to kill NLA thread. Message: %s (%d).\n", |
| |
863 msg, errorid); |
| |
864 g_free(msg); |
| |
865 } |
| |
866 } |
| |
867 g_static_mutex_unlock(&mutex); |
| |
868 |
| |
869 #endif |
| 800 purple_signal_unregister(purple_network_get_handle(), |
870 purple_signal_unregister(purple_network_get_handle(), |
| 801 "network-configuration-changed"); |
871 "network-configuration-changed"); |
| 802 } |
872 } |