@@ -20,6 +20,7 @@ import (
2020 "github.com/plgd-dev/go-coap/v3/options/config"
2121 "github.com/plgd-dev/go-coap/v3/pkg/cache"
2222 coapErrors "github.com/plgd-dev/go-coap/v3/pkg/errors"
23+ "github.com/plgd-dev/go-coap/v3/pkg/fn"
2324 coapSync "github.com/plgd-dev/go-coap/v3/pkg/sync"
2425 "github.com/plgd-dev/go-coap/v3/udp/coder"
2526 "go.uber.org/atomic"
@@ -288,21 +289,19 @@ func (cc *Conn) transmitMessage(req *pool.Message, waitForResponseChan chan stru
288289 return fmt .Errorf ("timeout: retransmission(%v) was exhausted" , cc .transmission .maxRetransmit .Load ())
289290}
290291
291- func (cc * Conn ) writeMessage (req * pool.Message ) error {
292- respChan := make (chan struct {})
293- req .UpsertType (message .Confirmable )
294- req .UpsertMessageID (cc .GetMessageID ())
292+ func (cc * Conn ) prepareWriteMessage (req * pool.Message , respChan chan struct {}) (func (), error ) {
293+ var closeFns fn.FuncList
295294
296295 // Only confirmable messages ever match an message ID
297296 switch req .Type () {
298297 case message .Confirmable :
299298 if req .Code () >= codes .GET && req .Code () <= codes .DELETE {
300299 if err := cc .acquireOutstandingInteraction (req .Context ()); err != nil {
301- return err
300+ return nil , err
302301 }
303- defer func () {
302+ closeFns = append ( closeFns , func () {
304303 cc .releaseOutstandingInteraction ()
305- }( )
304+ })
306305 }
307306 if _ , loaded := cc .midHandlerContainer .LoadOrStore (req .MessageID (), func (w * responsewriter.ResponseWriter [* Conn ], r * pool.Message ) {
308307 close (respChan )
@@ -312,17 +311,31 @@ func (cc *Conn) writeMessage(req *pool.Message) error {
312311 }
313312 cc .handleBW (w , r )
314313 }); loaded {
315- return fmt .Errorf ("cannot insert mid(%v) handler: %w" , req .MessageID (), coapErrors .ErrKeyAlreadyExists )
314+ closeFns .Execute ()
315+ return nil , fmt .Errorf ("cannot insert mid(%v) handler: %w" , req .MessageID (), coapErrors .ErrKeyAlreadyExists )
316316 }
317- defer func () {
317+ closeFns = append ( closeFns , func () {
318318 _ , _ = cc .midHandlerContainer .LoadAndDelete (req .MessageID ())
319- }( )
319+ })
320320 case message .NonConfirmable :
321321 /* TODO need to acquireOutstandingInteraction
322322 if req.Code() >= codes.GET && req.Code() <= codes.DELETE {
323323 }
324324 */
325325 }
326+ return closeFns .ToFunction (), nil
327+ }
328+
329+ func (cc * Conn ) writeMessage (req * pool.Message ) error {
330+ respChan := make (chan struct {})
331+ req .UpsertType (message .Confirmable )
332+ req .UpsertMessageID (cc .GetMessageID ())
333+
334+ closeFn , err := cc .prepareWriteMessage (req , respChan )
335+ if err != nil {
336+ return err
337+ }
338+ defer closeFn ()
326339
327340 if err := cc .session .WriteMessage (req ); err != nil {
328341 return fmt .Errorf (errFmtWriteRequest , err )
0 commit comments