mi: fix native return-value handling (#2537)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Jan-Otto Kröpke <mail@jkroepke.de>
This commit is contained in:
Jan-Otto Kröpke
2026-10-08 15:26:44 +02:00
committed by GitHub
co-authored by Claude Opus 5.5
parent b683caff8b
commit c280b5262b
9 changed files with 223 additions and 70 deletions
+19 -24
View File
@@ -98,8 +98,11 @@ func (s *Session) TestConnection() error {
operation := &Operation{}
// MI_Session_TestConnection returns void. The outcome, e.g. a timeout, is
// reported by GetInstance, and the operation must be closed either way.
//
// ref: https://github.com/KurtDeGreeff/omi/blob/9caa55032a1070a665e14fd282a091f6247d13c3/Unix/scriptext/py/PMI_Session.c#L92-L105
r0, _, _ := syscall.SyscallN(
_, _, _ = syscall.SyscallN(
s.ft.TestConnection,
uintptr(unsafe.Pointer(s)),
0,
@@ -107,18 +110,16 @@ func (s *Session) TestConnection() error {
uintptr(unsafe.Pointer(operation)),
)
if result := ResultError(r0); !errors.Is(result, MI_RESULT_OK) {
return result
_, _, err := operation.GetInstance()
if closeErr := operation.Close(); err == nil && closeErr != nil {
return fmt.Errorf("failed to close operation: %w", closeErr)
}
if _, _, err := operation.GetInstance(); err != nil {
if err != nil {
return fmt.Errorf("failed to get instance: %w", err)
}
if err := operation.Close(); err != nil {
return fmt.Errorf("failed to close operation: %w", err)
}
return nil
}
@@ -160,21 +161,25 @@ func (s *Session) QueryInstances(flags OperationFlags, operationOptions *Operati
return nil, err
}
return s.queryInstances(flags, operationOptions, namespaceName, queryDialect, queryExpressionUTF16)
return s.queryInstances(flags, operationOptions, namespaceName, queryDialect, queryExpressionUTF16), nil
}
// queryInstances starts an MI_Session_QueryInstances operation. Nil operationOptions
// fall back to the session defaults. The caller must close the returned operation.
//
// MI_Session_QueryInstances returns void: a failed query still yields an
// operation, and its status, e.g. a timeout or an invalid class, is reported
// by [Operation.GetInstance].
func (s *Session) queryInstances(flags OperationFlags, operationOptions *OperationOptions, namespaceName Namespace,
queryDialect QueryDialect, queryExpression Query,
) (*Operation, error) {
) *Operation {
operation := &Operation{}
if operationOptions == nil {
operationOptions = s.defaultOperationOptions
}
r0, _, _ := syscall.SyscallN(
_, _, _ = syscall.SyscallN(
s.ft.QueryInstances,
uintptr(unsafe.Pointer(s)),
uintptr(flags),
@@ -186,11 +191,7 @@ func (s *Session) queryInstances(flags OperationFlags, operationOptions *Operati
uintptr(unsafe.Pointer(operation)),
)
if result := ResultError(r0); !errors.Is(result, MI_RESULT_OK) {
return nil, result
}
return operation, nil
return operation
}
// unmarshalInstance populates structValue from instance using the `mi` struct tags.
@@ -368,10 +369,7 @@ func (s *Session) QueryUnmarshal[T any](dst *[]T,
return err
}
operation, err := s.queryInstances(flags, operationOptions, namespaceName, queryDialect, queryExpression)
if err != nil {
return fmt.Errorf("failed to query instances: %w", err)
}
operation := s.queryInstances(flags, operationOptions, namespaceName, queryDialect, queryExpression)
defer func() {
_ = operation.Close()
@@ -420,10 +418,7 @@ func (s *Session) QueryFunc(namespaceName Namespace, queryExpression Query, quer
}()
}
operation, err := s.queryInstances(OperationFlagsStandardRTTI, operationOptions, namespaceName, QueryDialectWQL, queryExpression)
if err != nil {
return fmt.Errorf("failed to query instances: %w", err)
}
operation := s.queryInstances(OperationFlagsStandardRTTI, operationOptions, namespaceName, QueryDialectWQL, queryExpression)
// Close cancels the operation if fn aborted it early.
defer func() {