Data handling improvement #1

Merged
esilva merged 3 commits from data-handling-improvement into master 2026-08-24 11:01:06 +01:00
10 changed files with 300 additions and 169 deletions
Showing only changes of commit 9adc0a9456 - Show all commits
+6 -3
View File
@@ -8,9 +8,10 @@ type Msg struct {
}
const (
MEMMAPFILENAME = "IRSDKMemMapFileName"
SimStatusUrl string = "http://127.0.0.1:32034/get_sim_status?object=simStatus"
IRSDK_DATAVALIDEVENTNAME string = "Local\\IRSDKDataValidEvent"
IRSDK_MEMMAPFILENAME string = "Local\\IRSDKMemMapFileName"
IRSDK_MEMMAPFILENAME string = "Local\\" + MEMMAPFILENAME
IRSDK_BROADCASTMSGNAME string = "IRSDK_BROADCASTMSG"
fileMapSize uint32 = 1164 * 1024
connTimeout int64 = 30
@@ -133,9 +134,11 @@ var (
irsdkPitSpeedLimiter = bitfieldValue{0x10, "irsdk_pitSpeedLimiter"}
irsdkRevLimiterActive = bitfieldValue{0x20, "irsdk_revLimiterActive"}
irsdkAbsActive = bitfieldValue{0x100, "irsdk_absActive"}
irsdkEngineWarnings = []bitfieldValue{irsdkWaterTempWarning, irsdkFuelPressureWarning,
irsdkEngineWarnings = []bitfieldValue{
irsdkWaterTempWarning, irsdkFuelPressureWarning,
irsdkOilPressureWarning, irsdkEngineStalled, irsdkPitSpeedLimiter, irsdkRevLimiterActive,
irsdkAbsActive}
irsdkAbsActive,
}
)
// enum irsdk_EngineWarnings
+7 -7
View File
@@ -1,11 +1,11 @@
package goirsdk
import (
"github.com/ESilva15/goirsdk/logger"
"bytes"
"encoding/binary"
"fmt"
"github.com/ESilva15/goirsdk/logger"
)
const (
@@ -28,18 +28,18 @@ func (i *IBT) readSubheader() error {
var subheaderRaw [SubHeaderSize]byte
_, err := i.File.ReadAt(subheaderRaw[:], HeaderSize)
if err != nil {
return fmt.Errorf("Failed to read disk subheaders from file: %v", err)
return fmt.Errorf("failed to read disk subheaders from file: %v", err)
}
i.SubHeaders, err = parseTelemetrySubHeader(subheaderRaw)
if err != nil {
return fmt.Errorf("Unable to parse disk subheaders from file: %v", err)
return fmt.Errorf("unable to parse disk subheaders from file: %v", err)
}
// Write to the output file - TODO add the check
if i.IBTExport != nil {
err = i.exportIBT(subheaderRaw[:], HeaderSize)
if i.Opts.IBTExport {
err = i.exportIBT(subheaderRaw[:], HeaderSize)
if err != nil {
log.Printf("Failed to export subheaders: %v\n", err)
log.Printf("failed to export subheaders: %v\n", err)
}
}
+10 -9
View File
@@ -3,7 +3,6 @@ package main
import (
"fmt"
"log"
"os"
"time"
"github.com/ESilva15/goirsdk"
@@ -14,21 +13,23 @@ func msToKph(v float32) int {
}
func main() {
// Open the data source file
file, err := os.Open("/path/to/ibtFile")
if err != nil {
log.Fatalf("Failed to open IBT file: %v", err)
}
// Instantiate our iRacing SDK instance
irsdk, err := goirsdk.Init(file, "", "")
irsdk, err := goirsdk.Init(goirsdk.Options{
SourceType: goirsdk.IBTFile,
SourcePath: "../../../testTelemetry/gt3_mustang_bathurst.ibt",
// SourcePath: "./exported.ibt",
IBTExportType: goirsdk.SharedMemoryFile,
// IBTExportPath: "./exported.ibt",
IBTExport: true,
})
if err != nil {
log.Fatalf("Failed to create iRacing interface: %v", err)
}
defer irsdk.Close()
// Set up a loop to iterate our data
mainLoopTicker := time.NewTicker(time.Second / 60)
// TODO: revert this 240 back to 60 because i recorded the thing wrong or whatever
mainLoopTicker := time.NewTicker(time.Second / 240)
defer mainLoopTicker.Stop()
for {
+19 -30
View File
@@ -1,11 +1,11 @@
package goirsdk
import (
"github.com/ESilva15/goirsdk/logger"
"bytes"
"encoding/binary"
"fmt"
"github.com/ESilva15/goirsdk/logger"
)
const (
@@ -15,30 +15,19 @@ const (
// TelemetryHeaders struct to hold an IBT file's headers
type TelemetryHeaders struct {
Version int32
// Status of 1 indicates a completed session and status of 0 a live session
Status int32
// TickRate indicates the frequency of writes (usually 60)
TickRate int32
// SessionInfoUpdate indicates the number of times the SessionInfo was
Version int32
Status int32 // Status of 1 indicates a completed session and status of 0 a live session
TickRate int32 // TickRate indicates the frequency of writes (usually 60)
SessionInfoUpdate int32 // SessionInfoUpdate indicates the number of times the SessionInfo was
// updated. 0 for finished sessions and >1 for active sessions
SessionInfoUpdate int32
// SessionInfoLength is the length of the session info buffer
SessionInfoLength int32
// SessionInfoOffset is the offset of the session info in the buffer
SessionInfoOffset int32
// NumVars is the number of variables in each input
NumVars int32
// VarHeaderOffset is the offset of the VarHeader
VarHeaderOffset int32
// NumBuf will be 1 for static files and 3 for live telemetry files
NumBuf int32
// BufLen is the length for parsing VarHeader values
BufLen int32
// Padding
Padding [12]byte
// I still don't know what this is:
BufOffset int32
SessionInfoLength int32 // SessionInfoLength is the length of the session info buffer
SessionInfoOffset int32 // SessionInfoOffset is the offset of the session info in the buffer
NumVars int32 // NumVars is the number of variables in each input
VarHeaderOffset int32 // VarHeaderOffset is the offset of the VarHeader
NumBuf int32 // NumBuf will be 1 for static files and 3 for live telemetry files
BufLen int32 // BufLen is the length for parsing VarHeader values
Padding [12]byte // Padding
BufOffset int32 // I still don't know what this is:
}
// readHeader will read the header out of the telemetry data
@@ -48,18 +37,18 @@ func (i *IBT) readHeader() error {
var headerRaw [FileHeaderSize]byte
_, err := i.File.ReadAt(headerRaw[:], 0)
if err != nil {
return fmt.Errorf("Failed to read headers from file: %v", err)
return fmt.Errorf("failed to read headers from file: %v", err)
}
i.Headers, err = parseTelemetryHeader(headerRaw)
if err != nil {
return fmt.Errorf("Unable to read headers from file: %v", err)
return fmt.Errorf("unable to read headers from file: %v", err)
}
// Write to the output file - TODO: this should only write if necessary
if i.IBTExport != nil {
err = i.exportIBT(headerRaw[:], 0)
if i.Opts.IBTExport {
err = i.exportIBT(headerRaw[:], 0)
if err != nil {
log.Printf("Failed to export headers: %v\n", err)
log.Printf("Failed to export headers: %v\n", err)
}
}
+117 -62
View File
@@ -3,23 +3,15 @@ package goirsdk
import (
"fmt"
"io"
"os"
"io"
"github.com/ESilva15/goirsdk/logger"
"github.com/ESilva15/goirsdk/sharedMem"
"github.com/ESilva15/goirsdk/winutils"
"gopkg.in/yaml.v3"
)
const (
ibtFile = "./telemetryFiles/mx5_2016Okayama_full_2024_10_19_22_02_12.ibt"
)
func msToKph(v float32) int {
return int((3600 * v) / 1000)
}
// Reader is an interface to represent the readable data that can be either
// a .ibt file (or live data, hopefully)
type Reader interface {
@@ -28,18 +20,47 @@ type Reader interface {
io.ReadCloser
}
type Writer interface {
io.WriterAt
io.Closer
}
type TelemetryContainer int
const (
IBTFile TelemetryContainer = iota
SharedMemoryFile TelemetryContainer = iota
)
type Options struct {
SourceType TelemetryContainer // type of source data
SourcePath string // Path to source
IBTExportType TelemetryContainer // export type of telemetry: store .ibt or replay in shm
IBTExportPath string // path where to export the data
IBTExport bool // whether to export the telemetry data
SessionInfoExport bool // whether to export the session info data
SessionInfoExportPath string // path where to export the session info
}
// IBT struct will hold the relevant data for a given IBT file
type IBT struct {
File Reader // Source of the data
IBTExport *os.File // If set, it will export the IBT data to the file
IBTExportPath string // Path for IBT export
YAMLExport *os.File // If set, it will export the session YAML to the file
YAMLExportPath string // Path for YAML export
Headers *TelemetryHeaders // IBT file Headers
SubHeaders *DiskSubHeader // IBT file Sub Headers
SessionInfo *SessionInfoYAML // IBT file Session Info
Vars *TelemetryVars // Vars will hold the telemetry data
winUtils *winutils.IRacingWinUtils // WinUtils gives access to the system utilities
File Reader // Source of the data
Opts Options
// TODO: IBTExporter should be an interface because we need to support shm too
IBTExporter Writer
// IBTExport *os.File // If set, it will export the IBT data to the file
// IBTExportPath string // Path for IBT export
// YAMLExport *os.File // If set, it will export the session YAML to the file
// YAMLExportPath string // Path for YAML export
winUtils *winutils.IRacingWinUtils // WinUtils gives access to the system utilities
// TODO: fragment this struct a little bit, for now I want to actually get
// stuff done so its enough to work as is
// Actual FILE
Headers *TelemetryHeaders // IBT file Headers
SubHeaders *DiskSubHeader // IBT file Sub Headers
SessionInfo *SessionInfoYAML // IBT file Session Info
Vars *TelemetryVars // Vars will hold the telemetry data
}
func (i *IBT) IsConnected() bool {
@@ -58,7 +79,7 @@ func (i *IBT) IsConnected() bool {
func (i *IBT) exportYAML() error {
log := logger.GetInstance()
file, err := os.OpenFile(i.YAMLExportPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644)
file, err := os.OpenFile(i.Opts.SessionInfoExportPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0o644)
if err != nil {
log.Printf("Failed to open file for YAML export: %v\n", err)
return fmt.Errorf("failed to open output file for YAML: %v", err)
@@ -79,11 +100,10 @@ func (i *IBT) exportYAML() error {
func (i *IBT) exportIBT(data []byte, offset int64) error {
log := logger.GetInstance()
_, err := i.IBTExport.WriteAt(data, offset)
_, err := i.IBTExporter.WriteAt(data, offset)
if err != nil {
i.IBTExport.Close()
i.IBTExport = nil
i.IBTExporter.Close()
i.IBTExporter = nil
log.Println("Won't attempt to export anymore")
return err
}
@@ -91,61 +111,96 @@ func (i *IBT) exportIBT(data []byte, offset int64) error {
return nil
}
// Init serves to initialize and get a hold of a IBT struct
// f -> is the source data, pass nil for the SDK to read live data or a
// *os.File to read from a file
// exportTelem -> is a string with the path to export the telemetry data, pass
// an empty string to not export any data
// exportTelem -> is a string with the path to export the session info data, pass
// an empty string to not export any data
func Init(f Reader, exportTelem string, exportYAML string) (*IBT, error) {
// log := logger.GetInstance()
// Read the header of the file
func (i *IBT) openSource() error {
var err error
ibt := IBT{
File: f,
IBTExport: nil,
IBTExportPath: exportTelem,
YAMLExport: nil,
YAMLExportPath: exportYAML,
Vars: &TelemetryVars{},
winUtils: nil,
}
// If requested to output to a telemetry file
if exportTelem != "" {
ibt.IBTExport, err = os.OpenFile(exportTelem, os.O_CREATE|os.O_RDWR, 0644)
if err != nil {
return nil, fmt.Errorf("failed to open ibt export file: %v", err)
}
}
if ibt.File == nil {
switch i.Opts.SourceType {
case SharedMemoryFile:
// User is requesting us to read live data - present in the mem map file
ibt.File, err = winutils.OpenMemMap(IRSDK_MEMMAPFILENAME, fileMapSize)
i.File, err = winutils.OpenMemMap(IRSDK_MEMMAPFILENAME, fileMapSize)
if err != nil {
return nil, fmt.Errorf("Failed to open memory mapped file: %v", err)
return fmt.Errorf("failed to open memory mapped file: %v", err)
}
// To use our windows interface we need to initialize it first
// it will return a struct with a pointer to the windows handles
// if, for some reason, we need to stub out this to run in on Linux its easier
ibt.winUtils, err = winutils.Init()
i.winUtils, err = winutils.Init()
if err != nil {
return nil, err
return err
}
// We need to open the windows event thing
err = ibt.winUtils.OpenWinEvent(IRSDK_DATAVALIDEVENTNAME)
err = i.winUtils.OpenWinEvent(IRSDK_DATAVALIDEVENTNAME)
if err != nil {
return nil, err
return err
}
// We need to open the broadcast channel
err = ibt.winUtils.OpenBroadcastChannel(IRSDK_BROADCASTMSGNAME)
err = i.winUtils.OpenBroadcastChannel(IRSDK_BROADCASTMSGNAME)
if err != nil {
return nil, err
return err
}
case IBTFile:
i.File, err = os.Open(i.Opts.SourcePath)
if err != nil {
return fmt.Errorf("failed to open file `%s`: %+v", i.Opts.SourcePath, err)
}
default:
return fmt.Errorf("a source type must be specified")
}
return nil
}
func (i *IBT) openExporter() error {
var err error
switch i.Opts.IBTExportType {
case SharedMemoryFile:
// Lets create a shared memory file!
shm, err := sharedMem.Create(MEMMAPFILENAME, fileMapSize)
if err != nil {
return fmt.Errorf("unable to create memory map file: %+v", err)
}
i.IBTExporter = shm
case IBTFile:
i.IBTExporter, err = os.OpenFile(i.Opts.IBTExportPath, os.O_CREATE|os.O_RDWR, 0o644)
if err != nil {
return fmt.Errorf("failed to open ibt export file: %v", err)
}
}
return nil
}
// Init serves to initialize and get a hold of a IBT struct
// Receives an Options struct with the required configurations
func Init(opts Options) (*IBT, error) {
// log := logger.GetInstance()
// Create our irsdk instance
var err error
ibt := IBT{
Opts: opts,
Vars: &TelemetryVars{},
winUtils: nil,
}
// Setup the source
err = ibt.openSource()
if err != nil {
return nil, err
}
// Setup the IBT data export - can be either shared memory or data file
if opts.IBTExport {
err = ibt.openExporter()
if err != nil {
// We log this only, or return some type of message
// Set the option to false so we won't export
ibt.Opts.IBTExport = false
}
}
+3 -3
View File
@@ -30,7 +30,7 @@ func lapTimeRepresentation(t float32) string {
}
func TestFunctionality(t *testing.T) {
input, err := os.Open("../testTelemetry/supercars_race_watkins_glenn.ibt")
input, err := os.Open("../../testTelemetry/supercars_race_watkins_glenn.ibt")
if err != nil {
t.Fatal("Was unable to prepare telemetry file for testing.")
}
@@ -62,7 +62,7 @@ func TestFunctionality(t *testing.T) {
// driversBehind := i.Vars.Vars["CarIdxF2Time"].Value.([]float32)
drivers := i.SessionInfo.DriverInfo.Drivers
myIdx := i.SessionInfo.DriverInfo.DriverCarIdx
myIdx := i.SessionInfo.DriverInfo.DriverCarIdx
standings := make([]StandingsLine, len(drivers))
@@ -90,7 +90,7 @@ func TestFunctionality(t *testing.T) {
return standings[i].LapPct >= standings[j].LapPct
})
fmt.Printf("%v\n", driversEstTime)
fmt.Printf("%v\n", driversEstTime)
// for p, v := range standings {
// fmt.Printf("[%2d] %-30s %13f %13f\n",
// p+1, v.DriverName, v.LapPct, driversEstTime[p] - driversEstTime[myIdx])
+4 -4
View File
@@ -1,13 +1,13 @@
package goirsdk
import (
"github.com/ESilva15/goirsdk/logger"
"encoding/json"
"fmt"
"log"
"strings"
"github.com/ESilva15/goirsdk/logger"
"golang.org/x/text/encoding/charmap"
"gopkg.in/yaml.v3"
)
@@ -321,7 +321,7 @@ func (i *IBT) readSessionInfo() error {
}
// Write to the output file
if i.IBTExport != nil {
if i.Opts.IBTExport {
err := i.exportIBT(sessionInfoStringRaw[:], int64(i.Headers.SessionInfoOffset))
if err != nil {
log.Printf("Failed to export offline telemetry data: %v", err)
@@ -334,7 +334,7 @@ func (i *IBT) readSessionInfo() error {
}
// Write to YAML output file
if i.YAMLExportPath != "" {
if i.Opts.SessionInfoExport {
err := i.exportYAML()
if err != nil {
log.Printf("Failed to export YAML string: %v\n", err)
+40 -17
View File
@@ -40,11 +40,13 @@ var (
}
)
type IRacingState int
type VarType struct {
Size int // Size is the var type size in bytes
Name string // Name is the irsdk var name
}
type (
IRacingState int
VarType struct {
Size int // Size is the var type size in bytes
Name string // Name is the irsdk var name
}
)
type IBTVar struct {
Type int32
@@ -106,9 +108,10 @@ type varBuffer struct {
}
type TelemetryVars struct {
Tick int32 // Keeps track of the current data buffer tick
RecorderTick int32 // Counts from 0 when creating a telemetry file from a replay or live data
Vars map[string]Var // Variables content
Tick int32 // Keeps track of the current data buffer tick
RecorderTick int32 // Counts from 0 when creating a telemetry file from a
// replay or live data
Vars map[string]Var // Variables content
}
func (i *IBT) readVariablerHeaders() error {
@@ -123,7 +126,7 @@ func (i *IBT) readVariablerHeaders() error {
return err
}
if i.IBTExport != nil {
if i.Opts.IBTExport {
err = i.exportIBT(rbuf, int64(i.Headers.VarHeaderOffset+k*VarHeaderSize))
if err != nil {
// Don't outright kill it here - maybe nowhere else
@@ -306,6 +309,7 @@ func (i *IBT) readData(buf []byte) error {
// Update will read the next data chunk from the telemetry data, works for both the
// live and offline data
func (i *IBT) Update(timeout time.Duration) (IRacingState, error) {
// This is what happens if we are reading live data
if i.winUtils != nil {
// Put a way to check if the sim is active here
// fmt.Println("NOT CHECKING IF SIM IS ACTIVE - ADD ME")
@@ -344,10 +348,19 @@ func (i *IBT) Update(timeout time.Duration) (IRacingState, error) {
return Failed, err
}
if i.IBTExport != nil {
err = i.exportIBT(buf, int64(i.Headers.BufOffset+i.Vars.RecorderTick*i.Headers.BufLen))
if err != nil {
log.Printf("Failed to export live telemetry data: %v", err)
if i.Opts.IBTExport {
// Dirty attempt at getting this to work to write to a memory mapped file
switch i.Opts.IBTExportType {
case IBTFile:
err = i.exportIBT(buf, int64(i.Headers.BufOffset+i.Vars.RecorderTick*i.Headers.BufLen))
if err != nil {
log.Printf("Failed to export live telemetry data: %v", err)
}
case SharedMemoryFile:
err = i.exportIBT(buf, int64(i.Headers.BufOffset))
if err != nil {
log.Printf("Failed to export live telemetry data: %v", err)
}
}
}
@@ -363,6 +376,7 @@ func (i *IBT) Update(timeout time.Duration) (IRacingState, error) {
// Document why this is here, I don't remember the exact words right now
i.Vars.RecorderTick++
} else {
// This is what happens if we are reading from an .ibt file
// This will get the dataframe corresponding to a given tick
start := i.Headers.BufOffset + i.Vars.Tick*i.Headers.BufLen
buf := make([]byte, i.Headers.BufLen)
@@ -370,10 +384,19 @@ func (i *IBT) Update(timeout time.Duration) (IRacingState, error) {
// Make this happen in a different thread, or have this send to a queue that has a thread
// writing to a file
if i.IBTExport != nil {
err = i.exportIBT(buf, int64(start))
if err != nil {
log.Printf("Failed to export offline telemetry data: %v", err)
if i.Opts.IBTExport {
// Dirty attempt at getting this to work to write to a memory mapped file
switch i.Opts.IBTExportType {
case IBTFile:
err = i.exportIBT(buf, int64(start))
if err != nil {
log.Printf("Failed to export offline telemetry data: %v", err)
}
case SharedMemoryFile:
err = i.exportIBT(buf, int64(i.Headers.BufOffset))
if err != nil {
log.Printf("Failed to export live telemetry data: %v", err)
}
}
}
+88 -25
View File
@@ -1,53 +1,116 @@
//go:build (linux && cgo) || (darwin && cgo)
// +build linux,cgo darwin,cgo
package winutils
import (
"errors"
"sync"
"fmt"
"net"
"os"
"time"
)
const (
WAIT_OBJECT_0 = 0
WAIT_TIMEOUT = 258
)
var (
once sync.Once
ErrUnsupportedOS = errors.New("not found")
)
type utils struct {
socketPath string
listener *net.UnixConn
}
// INITIALIZATION
func newUtils() (*utils, error) {
return nil, ErrUnsupportedOS
return &utils{}, nil
}
func (u *utils) Close() {
if u.listener != nil {
u.listener.Close()
os.Remove(u.socketPath)
}
}
// openEvent opens a windows.Handle for a given event
// OpenEvent creates or connects to a Unix socket for event signaling on Linux
func (u *utils) OpenEvent(eventName string) error {
return ErrUnsupportedOS
u.socketPath = fmt.Sprintf("/tmp/iracing_%s.sock", eventName)
_ = os.Remove(u.socketPath)
addr, err := net.ResolveUnixAddr("unixgram", u.socketPath)
if err != nil {
return err
}
l, err := net.ListenUnixgram("unixgram", addr)
if err != nil {
return err
}
u.listener = l
return nil
}
// OpenBroadcastChannel opens up a broadcast channel to send commands to iracing
func (u *utils) OpenBroadcastChannel(name string) error {
return ErrUnsupportedOS
// No-op or log stub on Linux
return nil
}
// INITIALIZATION
// openEvent waits for a good response for some given time
// CheckValidDataEvent waits for a pulse byte sent over the socket
func (u *utils) CheckValidDataEvent(timeout time.Duration) bool {
return false
if u.listener == nil {
return false
}
_ = u.listener.SetReadDeadline(time.Now().Add(timeout))
buf := make([]byte, 1)
_, err := u.listener.Read(buf)
return err == nil
}
// SendBroadcastMessage sends a message trough the broadcast channel
func (u *utils) SendBroadcastMessage(id, p1, p2 uintptr) error {
return ErrUnsupportedOS
return nil
}
// package winutils
//
// import (
// "errors"
// "sync"
// "time"
// )
//
// const (
// WAIT_OBJECT_0 = 0
// WAIT_TIMEOUT = 258
// )
//
// var (
// once sync.Once
// ErrUnsupportedOS = errors.New("not found")
// )
//
// type utils struct {
// }
//
// // INITIALIZATION
// func newUtils() (*utils, error) {
// return nil, ErrUnsupportedOS
// }
//
// func (u *utils) Close() {
// }
//
// // openEvent opens a windows.Handle for a given event
// func (u *utils) OpenEvent(eventName string) error {
// return ErrUnsupportedOS
// }
//
// // OpenBroadcastChannel opens up a broadcast channel to send commands to iracing
// func (u *utils) OpenBroadcastChannel(name string) error {
// return ErrUnsupportedOS
// }
//
// // INITIALIZATION
//
// // openEvent waits for a good response for some given time
// func (u *utils) CheckValidDataEvent(timeout time.Duration) bool {
// return false
// }
//
// // SendBroadcastMessage sends a message trough the broadcast channel
// func (u *utils) SendBroadcastMessage(id, p1, p2 uintptr) error {
// return ErrUnsupportedOS
// }
+6 -9
View File
@@ -1,5 +1,4 @@
//go:build windows && cgo
// +build windows,cgo
// go:build windows
package winutils
@@ -16,13 +15,11 @@ const (
WAIT_TIMEOUT = 258
)
var (
once sync.Once
)
var once sync.Once
type utils struct {
user32DLL *windows.LazyDLL
wEvent *windows.Handle
wEvent windows.Handle
wBroadcastChn uintptr
}
@@ -34,7 +31,7 @@ func newUtils() (*utils, error) {
}
func (u *utils) Close() {
closeEvent(u.wEvent)
closeEvent(&u.wEvent)
// Do we need to unload the user32DLL ???
// Do we need to close the broadcast channel ???
}
@@ -50,7 +47,7 @@ func (u *utils) OpenEvent(eventName string) error {
if err != nil {
return err
}
u.wEvent = &event
u.wEvent = event
return nil
}
@@ -90,7 +87,7 @@ func (u *utils) CheckValidDataEvent(timeout time.Duration) bool {
t0 := time.Now().UnixNano()
timeoutInt := uint32(timeout / time.Millisecond)
result, err := windows.WaitForSingleObject(*u.wEvent, timeoutInt)
result, err := windows.WaitForSingleObject(u.wEvent, timeoutInt)
if err != nil {
remaining := timeoutInt - uint32((time.Now().UnixNano()-t0)/1000000)
if remaining > 0 {