Skip to content

fix: lock thread in coinitService #10

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions wmi.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,9 @@ var DefaultClient = &Client{}

// coinitService coinitializes WMI service. If no error is returned, a cleanup function
// is returned which must be executed (usually deferred) to clean up allocated resources.
// Because coinitServer calls ole.CoInitializeEx, which uses thread specific resources,
// the caller must call the deferred cleanup function on the same go routine that
// called coinitService.
func (c *Client) coinitService(connectServerArgs ...interface{}) (*ole.IDispatch, func(), error) {
var unknown *ole.IUnknown
var wmi *ole.IDispatch
Expand All @@ -141,6 +144,7 @@ func (c *Client) coinitService(connectServerArgs ...interface{}) (*ole.IDispatch
unknown.Release()
}
ole.CoUninitialize()
runtime.UnlockOSThread()
}

// if we error'ed here, clean up immediately
Expand All @@ -151,6 +155,8 @@ func (c *Client) coinitService(connectServerArgs ...interface{}) (*ole.IDispatch
}
}()

runtime.LockOSThread()

err = ole.CoInitializeEx(0, ole.COINIT_MULTITHREADED)
if err != nil {
oleCode := err.(*ole.OleError).Code()
Expand Down Expand Up @@ -239,8 +245,6 @@ func (c *Client) Query(query string, dst interface{}, connectServerArgs ...inter

lock.Lock()
defer lock.Unlock()
runtime.LockOSThread()
defer runtime.UnlockOSThread()

service, cleanup, err := c.coinitService(connectServerArgs...)
if err != nil {
Expand Down Expand Up @@ -368,7 +372,7 @@ func (c *Client) loadEntity(dst interface{}, src *ole.IDispatch) (errFieldMismat
f = f.Elem()
}

if prop.VT == 0x1 { //VT_NULL
if prop.VT == 0x1 { // VT_NULL
continue
}

Expand Down Expand Up @@ -467,7 +471,7 @@ func (c *Client) loadEntity(dst interface{}, src *ole.IDispatch) (errFieldMismat
Reason: "not a Float64",
}
}

default:
if f.Kind() == reflect.Slice {
switch f.Type().Elem().Kind() {
Expand Down