X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=core%2Fchannel.go;h=112c14e28baf6dbba38f9c76af2ea77c9bbd2bbe;hb=a4112fac7b86fe09650d2bb57969fe46404edd7d;hp=fbb3e5938e00248df130f7ff42688c61a93b6fd2;hpb=bcf3fbd21aa22d1546bc85ffb887ae5ba557808e;p=govpp.git diff --git a/core/channel.go b/core/channel.go index fbb3e59..112c14e 100644 --- a/core/channel.go +++ b/core/channel.go @@ -37,8 +37,8 @@ type MessageCodec interface { EncodeMsg(msg api.Message, msgID uint16) ([]byte, error) // DecodeMsg decodes binary-encoded data of a message into provided Message structure. DecodeMsg(data []byte, msg api.Message) error - // DecodeMsgContext decodes context from message data. - DecodeMsgContext(data []byte, msg api.Message) (context uint32, err error) + // DecodeMsgContext decodes context from message data and type. + DecodeMsgContext(data []byte, msgType api.MessageType) (context uint32, err error) } // MessageIdentifier provides identification of generated API messages. @@ -109,17 +109,36 @@ type Channel struct { receiveReplyTimeout time.Duration // maximum time that we wait for receiver to consume reply } -func newChannel(id uint16, conn *Connection, codec MessageCodec, identifier MessageIdentifier, reqSize, replySize int) *Channel { - return &Channel{ - id: id, - conn: conn, - msgCodec: codec, - msgIdentifier: identifier, - reqChan: make(chan *vppRequest, reqSize), - replyChan: make(chan *vppReply, replySize), +func (c *Connection) newChannel(reqChanBufSize, replyChanBufSize int) (*Channel, error) { + // create new channel + channel := &Channel{ + conn: c, + msgCodec: c.codec, + msgIdentifier: c, + reqChan: make(chan *vppRequest, reqChanBufSize), + replyChan: make(chan *vppReply, replyChanBufSize), replyTimeout: DefaultReplyTimeout, receiveReplyTimeout: ReplyChannelTimeout, } + + // store API channel within the client + c.channelsLock.Lock() + if len(c.channels) >= 0x7fff { + return nil, errors.New("all channel IDs are used") + } + for { + c.nextChannelID++ + chID := c.nextChannelID & 0x7fff + _, ok := c.channels[chID] + if !ok { + channel.id = chID + c.channels[chID] = channel + break + } + } + c.channelsLock.Unlock() + + return channel, nil } func (ch *Channel) GetID() uint16 {