diff --git a/conn.go b/conn.go index bbe111b..ab81c8a 100644 --- a/conn.go +++ b/conn.go @@ -7,6 +7,7 @@ import ( "os" "strings" "sync" + "time" ) var ( @@ -30,8 +31,9 @@ var ErrClosed = errors.New("dbus: connection closed by user") type Conn struct { transport - ctx context.Context - cancelCtx context.CancelFunc + ctx context.Context + cancelCtx context.CancelFunc + defaultTimeout time.Duration closeOnce sync.Once closeErr error @@ -258,6 +260,14 @@ func WithContext(ctx context.Context) ConnOption { } } +// WithDefaultSendTimeout supplies the connection with a default timeout for outgoing messages. +func WithDefaultSendTimeout(timeout time.Duration) ConnOption { + return func(conn *Conn) error { + conn.defaultTimeout = timeout + return nil + } +} + // NewConn creates a new private *Conn from an already established connection. func NewConn(conn io.ReadWriteCloser, opts ...ConnOption) (*Conn, error) { return newConn(genericTransport{conn}, opts...) @@ -540,7 +550,16 @@ func (conn *Conn) send(ctx context.Context, msg *Message, ch chan *Call) *Call { } var call *Call - ctx, canceler := context.WithCancel(ctx) + var canceler context.CancelFunc + if ctx == context.TODO() { + if conn.defaultTimeout > 0 { + ctx, canceler = context.WithTimeout(context.Background(), conn.defaultTimeout) + } else { + ctx, canceler = context.WithCancel(context.Background()) + } + } else { + ctx, canceler = context.WithCancel(ctx) + } msg.serial = conn.getSerial() if msg.Type == TypeMethodCall && msg.Flags&FlagNoReplyExpected == 0 { call = new(Call) diff --git a/object.go b/object.go index b4b1e93..e8ae640 100644 --- a/object.go +++ b/object.go @@ -31,7 +31,7 @@ type Object struct { // Call calls a method with (*Object).Go and waits for its reply. func (o *Object) Call(method string, flags Flags, args ...interface{}) *Call { - return <-o.createCall(context.Background(), method, flags, make(chan *Call, 1), args...).Done + return <-o.createCall(context.TODO(), method, flags, make(chan *Call, 1), args...).Done } // CallWithContext acts like Call but takes a context @@ -90,7 +90,7 @@ func (o *Object) RemoveMatchSignal(iface, member string, options ...MatchOption) // If the method parameter contains a dot ('.'), the part before the last dot // specifies the interface on which the method is called. func (o *Object) Go(method string, flags Flags, ch chan *Call, args ...interface{}) *Call { - return o.createCall(context.Background(), method, flags, ch, args...) + return o.createCall(context.TODO(), method, flags, ch, args...) } // GoWithContext acts like Go but takes a context