c++ - WinInet and InternetOpen -


the documentation states internetopen can called multiple times without issues. question though should calling internetclosehandle on handle returned multiple times?

for example, have class call capirequestcontext, has handle returned internetopen. each 1 of requests has it's own copy. right now, call internetclosehandle in destructor, gets called multiple times.

i'm wondering if following cause issues: thread creates capirequestobject calls internetopen , stores handle. thread b same, goes out of scope before thread exits, thread b calls destructor in it's own capirequestobject, calls internetclosehandle on handle returned internetopen.

should remove call internetclosehandle in destructors of class? @ least internethandle? assume should call internetclosehandle handle returned httpopenrequest.

i have similar questions regarding handle returned internetconnect. these handles shared?

here sample code, minus external code don't think related issue:

class capiclient; class capirequest { public:      capirequestcontext()      {          m_hconn = null;          m_hinternet = null;          m_hrequest = null;      }       ~capirequestcontext()      {          if (m_hrequest) internetclosehandle(m_hrequest);          if (m_hconn) internetclosehandle(m_hconn);          if (m_hinternet) internetclosehandle(m_hinternet);      }       bool init(const capiclient &client, const std::string &uri, const std::string &method)      {           atlassert(!(m_hinternet || m_hconn || m_hrequest));           if (m_hinternet || m_hconn || m_hrequest) throw std::exception("cannot init request more once.");            bool success = false;           m_authtoken = *client.m_pauthtoken;           uri = uri;           m_hinternet = internetopen("myapp", internet_open_type_preconfig, null, null, 0); dword requesttimeout = 60 * 1000; // set timeout 60 seconds instead of 30            if (m_hinternet)           {                   internetsetoption(m_hinternet, internet_option_receive_timeout, &requesttimeout, sizeof(requesttimeout));                 m_hconn = internetconnect(m_hinternet, (lpstr)client.m_host.c_str(), client.m_port, null, null, internet_service_http, 0, (dword_ptr)this);                 if (m_hconn) {                       m_hrequest = httpopenrequest(m_hconn, method.c_str(), uri.c_str(), "http/1.1", null, null, client.getopenrequestflags(), 0);                 }                 if (m_hrequest)                 {                     success = true;                 }           }        return success;      }       }      // there additional calls      // sendrequest     // getdata     // getfullresponse  private:      // added these methods make sure i'm not copying handles enter code here      capirequestcontext(const capirequestcontext &other) = delete;      capirequestcontext& operator=(const capirequestcontext& other) = delete;  private:       hinternet m_hinternet;       hinternet m_hconn;       hinternet m_hrequest;  } 

the documentation states internetopen can called multiple times without issues. question though should calling internetclosehandle on handle returned multiple times?

yes, stated in internetopen() documentation:

after calling application has finished using hinternet handle returned internetopen, it must closed using internetclosehandle function.

for example, have class call capirequestcontext, has handle returned internetopen. each 1 of requests has it's own copy. right now, call internetclosehandle in destructor, gets called multiple times.

that correct implementation, if each instance of class calls internetopen(), or otherwise obtains ownership of unique hinternet.

however, aware such class needs implement rule of three. basically, if have provide destructor release resource, need provide copy-constructor , copy-assignment operator well.

but, can't call internetclosehandle() multiple times on same hinternet, can't have multiple capirequestcontext using same hinternet , of them calling internetclosehandle()1. so, copy constructor , copy-assignment operator must either:

  1. take ownership of hinternet source capirequestcontext being copied.

  2. be disabled prevent copying 1 capirequestcontext another.

in case, opt #2.

1: need per-instance flag indicating instance can call , ones cannot. not class design. if need share hinternet, should implement reference counting semantics instead, such provided std::shared_ptr.

i'm wondering if following cause issues: thread creates capirequestobject calls internetopen , stores handle. thread b same, goes out of scope before thread exits, thread b calls destructor in it's own capirequestobject, calls internetclosehandle on handle returned internetopen.

that safe, provided each capirequestobject has own hinternet.

should remove call internetclosehandle in destructors of class?

no, if each class instance holds unique hinternet.

i assume should call internetclosehandle handle returned httpopenrequest.

yes, stated in httpopenrequest() documentation:

after calling application has finished using hinternet handle returned httpopenrequest, it must closed using internetclosehandle function.

i have similar questions regarding handle returned internetconnect. these handles shared?

each hinternet must closed individually.