Archived

This forum has been archived. Please start a new discussion on GitHub.

socket error

Hello,

I am getting the following error when shutting down a python application:
foo.py: error: exception in `Ice.ThreadPool.Client' while calling closeSocket():
.\Network.cpp:233: Ice::SocketException:
socket exception: WSANOTINITIALISED

Actually, it is a python application that links to some C++ libraries that link with Ice. I haven't been able to build debug. Can you give me any idea of what might be happening? Any suggestions would be welcome.

Thanks,
Edward

Comments

  • Here is a description of the error code:
    Successful WSAStartup not yet performed.
    Either the application has not called WSAStartup or WSAStartup failed. The application may be accessing a socket that the current active task does not own (that is, trying to share a socket between tasks), or WSACleanup has been called too many times.

    Ice properly initializes and de-initializes Windows sockets, so the problem must be somewhere in the code you are linking with.
  • I am sharing a proxy handle between threads, that is probably the problem. Why am I doing that? Well I am creating a library with some functions that have C linkage:

    extern MyPrx myProxyHandle;
    ...
    extern "C" void my_error(int n, char* msg)
    {
        ostringstream ss;
        ss << "error: " << n << ":" << msg << endl;
        if (myProxyHandle) {
            myProxyHandle->Print(ss.str());
        }
        else {
            cout << ss.str() << endl;
        }
    }
    

    So myProxyHandle is a global variable. It is set by the main app run routine:
                ...
                Ice::ObjectPrx base = c->stringToProxy(myProxyString);
                myProxyHandle = MyProj::MyPrx::checkedCast(base);
    
    I guess I could put that code into each of the C routines where I access the proxy, thus making the handle local to each function. What would you suggest?

    Thanks,
    Edward
  • There is nothing wrong with sharing a proxy among several threads. Proxies are fully thread safe.
  • I still can't figure this one out. I have shrunk everything down to a very small piece of code and wonder if you wouldn't give it another look. I am building against the demo/hello code.

    If I make HelloPrx myPrx a local variable then everything runs smoothly, but if I leave it as a global then I get the Ice::SocketException I described previously.
    #include <Ice/Ice.h>
    #include <Hello.h>
    #include <Ice/Application.h>
    #include <IceUtil/Options.h>
    
    using namespace std;
    using namespace Demo;
    
    
    class Main : public Ice::Application
    {
    public:
        virtual int run(int, char*[]);
    };
    
    int main(int argc, char* argv[]) {
        Main app;
        return app.main(argc, argv);
    }
    
    extern "C" void zzz_main_main (int argc, char *argv[])
    {
        main(argc, argv);
    };
    
    HelloPrx myPrx;
    
    int Main::run(int argc, char* argv[])
    {
        Ice::CommunicatorPtr c(communicator());
    
    	Ice::ObjectPrx base = c->stringToProxy("hello:tcp -p 10000");
        myPrx = HelloPrx::checkedCast(base);
        if (!myPrx) {
            cerr << "Invalid proxy: " << endl;
        }
    	
        return EXIT_SUCCESS;
    }
    

    Now the tricky part of this is that the above code gets linked into a python library called pyzzz (I use swig to create the inter-language glue). A python program can invoke zzz_main_main() which invokes main(). When main() exits I get the error message.

    Somehow there is a strange interaction between the python interpreter and the global proxy. Any ideas?

    Thanks again,
    Edward
  • bernard
    bernard Jupiter, FL
    Hi Edward,

    One problem with your code sample is that your main function (and Main::run) return immediately: this destroys the communicator and makes your proxy invalid.

    The error "WSANOTINITIALISED" occurs when there is no communicator alive in your process. I am surprised you don't get a more meaningful exception, such as CommunicatorDestroyedException. Which Ice version do you use? The platform and C++ compiler could help as well.

    Also, note that you don't have to use Application--it's just a helper class. In your situation, it may be simpler to create a communicator and proxy directly, and maintain the communicator alive until you're done with them.

    Cheers,
    Bernard
  • Hi Bernard,

    Thanks for your response. The code I posted is distilled from a much more complicated application in which the Main::run() creates an adapter, a MainI class that spawns a worker thread derived from IceUtil::Thread. Main::run() does a join on the thread, so it doesn't exit immediately. I stripped all that out to make things as simple as possible.

    Having said that, are you saying that I should destroy the application communicator explicitly? Or should I destroy the proxy (e.g. myPrx = 0)?

    By the way, I managed to get a partial stack trace:
    >	_pyzzz.pyd!IceInternal::closeSocket(unsigned int fd=244)  Line 233	C++
     	_pyzzz.pyd!IceInternal::ThreadPool::~ThreadPool()  Line 146 + 0x10 bytes	C++
     	_pyzzz.pyd!IceInternal::ThreadPool::`scalar deleting destructor'()  + 0x8 bytes	C++
     	iceutil31.dll!00b8d0f4() 	
     	[Frames below may be incorrect and/or missing, no symbols loaded for iceutil31.dll]	
     	_pyzzz.pyd!Ice::ConnectionI::~ConnectionI()  Line 1552 + 0xc4 bytes	C++
     	_pyzzz.pyd!Ice::ConnectionI::`vector deleting destructor'()  + 0x57 bytes	C++
     	iceutil31.dll!00b8d0f4() 	
     	_pyzzz.pyd!IceDelegateM::Ice::Object::~Object()  Line 1112 + 0x15 bytes	C++
     	_pyzzz.pyd!IceDelegateM::Demo::Hello::`scalar deleting destructor'()  + 0xd bytes	C++
     	iceutil31.dll!00b8d0f4() 	
     	_pyzzz.pyd!IceProxy::Ice::Object::~Object()  + 0x3f bytes	C++
     	_pyzzz.pyd!IceProxy::Demo::Hello::`scalar deleting destructor'()  + 0x9 bytes	C++
     	iceutil31.dll!00b8d0f4() 	
     	_pyzzz.pyd!_CRT_INIT(void * hDllHandle=0x10000000, unsigned long dwReason=0, void * lpreserved=0x00000001)  Line 403	C
     	_pyzzz.pyd!__DllMainCRTStartup(void * hDllHandle=0x10000000, unsigned long dwReason=0, void * lpreserved=0x00000000)  Line 509 + 0x8 bytes	C
     	_pyzzz.pyd!_DllMainCRTStartup(void * hDllHandle=0x10000000, unsigned long dwReason=0, void * lpreserved=0x00000001)  Line 459 + 0x11 bytes	C
     	ntdll.dll!7c9011a7() 	
     	ntdll.dll!7c923f31() 	
     	ntdll.dll!7c910945() 	
     	ntdll.dll!7c91094e() 	
     	kernel32.dll!7c81cd76() 	
     	python24.dll!1e099337() 	
     	ntdll.dll!7c91056d() 	
     	msvcr71.dll!7c34218a() 	
     	msvcr71.dll!7c34218f() 	
     	msvcr71.dll!7c34214f() 	
     	msvcr71.dll!7c34f65c() 	
     	msvcr71.dll!7c34f742() 	
     	msvcr71.dll!7c34f739() 	
     	ntdll.dll!7c90f0aa() 	
     	kernel32.dll!7c81cdee() 	
     	msvcr71.dll!7c348d04() 	
     	msvcr71.dll!7c3476c9() 	
     	msvcr71.dll!7c348d11() 	
     	python.exe!1d0011b9() 	
     	kernel32.dll!7c816fd7() 	
    
  • benoit
    benoit Rennes, France
    Hi,

    No, you shouldn't need to explicitly destroy the communicator if you use Ice::Application. The application class will take care of it once your application run() method returns.

    As Marc mentioned, Ice correctly intializes and shutdown the Windows Socket library by calling WSAStartup/WSACleanup. The Windows Socket library should still be initialized at the point where the error shows up. However, for some reasons, it looks like in your application it's not initialized anymore at this point. Perhaps something else in your application called WSACleanup too many times? (see http://msdn2.microsoft.com/en-us/library/ms741549.aspx for more information on WSACleanup).

    Setting myPrx to 0 before the communicator is destroyed or before your main method returns could help to ensure all Ice objects are destroyed sooner rather than later and might avoid this problem. However, it would still be good to figure out why the Windows socket library isn't being properly initialized and cleanup since this might cause other issues down the road...

    Cheers,
    Benoit.