1 # fca-rcvr.tcl --
2 #
3 # FIXME: This file needs a description here.
4 #
5 # Copyright (c) 1997-2002 The Regents of the University of California.
6 # All rights reserved.
7 #
8 # Redistribution and use in source and binary forms, with or without
9 # modification, are permitted provided that the following conditions are met:
10 #
11 # A. Redistributions of source code must retain the above copyright notice,
12 # this list of conditions and the following disclaimer.
13 # B. Redistributions in binary form must reproduce the above copyright notice,
14 # this list of conditions and the following disclaimer in the documentation
15 # and/or other materials provided with the distribution.
16 # C. Neither the names of the copyright holders nor the names of its
17 # contributors may be used to endorse or promote products derived from this
18 # software without specific prior written permission.
19 #
20 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
21 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 # ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
24 # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26 # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31
32 ####? should this belong here
33 Class FloorGrant
34 FloorGrant instproc init {floorType floorInstance {grantSeqNo {}} {srcId {}} {requestId{}} } {
35 # requestId_ -- request to grant to
36 $self instvar srcId_ grantSeqNo_ floorType_ floorInstance_ requestId_
37 set srcId_ $srcId
38 set grantSeqNo_ $grantSeqNo
39 set floorType_ $floorType
40 set floorInstance_ $floorInstance
41 set requestId_ $requestId
42 }
43
44
45 Class FCAFloorRequest
46 FCAFloorRequest instproc init {srcId {requestId {}} {floorTypes {}} \
47 {comment {}} } {
48 $self next
49 $self instvar srcId_ requestId_ floorTypes_ comment_
50 set floorTypes_ $floorTypes
51 set requestId_ $requestId
52 set srcId_ $srcId
53 set comment_ $comment
54 }
55
56
57 # return a list which contains uid addr and comment of the request
58 FCAFloorRequest instproc request {} {
59 $self instvar requestId_ srcId_ comment_
60 return {$requestId_ $srcId_ $comment_}
61 }
62
63
64 FCAFloorRequest instproc requestId {} {
65 $self instvar requestId_
66 return $requestId_
67 }
68
69
70 FCAFloorRequest instproc srcId {} {
71 $self instvar srcId_
72 return $srcId_
73 }
74
75
76 FCAFloorRequest instproc floorTypes {} {
77 $self instvar floorTypes_
78 return $floorTypes_
79
80 }
81
82 FCAFloorRequest instproc comment {} {
83 $self instvar comment_
84 return $comment_
85 }
86
87
88
89 Class FCAAllRequests
90
91 FCAAllRequests instproc init { } {
92 $self set doneRequestId_ 0
93 $self set maxRequestId_ 0
94 }
95
96
97 FCAAllRequests instproc is_canceled { requestId } {
98 $self instvar requests_ doneRequestId_
99
100 if { $requestId <= $doneRequestId_ && \
101 ![info exists requests_($requestId)] } {
102 return 1
103 }
104
105 if { [info exists requests_($requestId)] && \
106 $requests_($requestId)=="canceled" } {
107 return 1
108 }
109 return 0
110 }
111
112
113 FCAAllRequests instproc have { requestId } {
114 $self instvar requests_
115 if { [info exists requests_($requestId)] } {
116 set request $requests_($requestId)
117 if { $request!={} && $request!="canceled" } {
118 return 1
119 }
120 }
121 return 0
122 }
123
124
125 FCAAllRequests instproc dont_have { requestId } {
126 $self instvar requests_ doneRequestId_
127 if { $requestId <= $doneRequestId_ } {
128 # we always have everything upto doneRequestId_
129 return 0
130 }
131
132 if { ![info exists requests_($requestId)] || $requests_($requestId)=={} } {
133 return 1
134 }
135 return 0
136 }
137
138
139 FCAAllRequests instproc incr { requestId } {
140 $self instvar requests_ doneRequestId_ maxRequestId_
141 if { $requestId > $maxRequestId_ } {
142 set maxRequestId_ $requestId
143 }
144
145 if { $requestId == [expr $doneRequestId_ + 1] } {
146 while { $doneRequestId_ < $maxRequestId_ && \
147 ![$self dont_have [expr $doneRequestId_+1] ]} {
148
149 if { [$self is_canceled [expr $doneRequestId_ + 1]] } {
150 unset requests_([expr $doneRequestId_ + 1])
151 }
152 incr doneRequestId_
153 }
154 }
155 }
156
157
158 # request may be "" indicating that we know this request is around, but we
159 # don't have the actual data yet
160 FCAAllRequests instproc got_request { requestId request } {
161 $self instvar requests_
162 set requests_($requestId) $request
163 $self incr $requestId
164 }
165
166
167 FCAAllRequests instproc cancel { requestId } {
168 $self instvar requests_ doneRequestId_
169
170 if { $requestId <= $doneRequestId_ } {
171 catch { unset requests_($requestId) }
172 return
173 }
174
175 if { [info exists requests_($requestId)] } {
176 set request $requests_($requestId)
177 if { $request!="" } {
178 delete $request
179 }
180 }
181
182 set requests_($requestId) "canceled"
183 $self incr $requestId
184 }
185
186
187 FCAAllRequests instproc get { requestId } {
188 $self instvar requests_
189 if { [info exists requests_($requestId)] } {
190 return $requests_($requestId)
191 } else {
192 return ""
193 }
194 }
195
196
197 FCAAllRequests instproc doneRequestId { } {
198 return [$self set doneRequestId_]
199 }
200
201
202 FCAAllRequests instproc maxRequestId { } {
203 return [$self set maxRequestId_]
204 }
205
206
207
208 Class FCAImportant
209 FCAImportant instproc init { } {
210 $self next
211 $self set maxSeqno_ 0
212 }
213
214
215 # type is either cancel or release
216 # id is the requestId for "cancel", grantSeqno for "release"
217
218 FCAImportant instproc add { type id } {
219 $self instvar list_ maxSeqno_
220 incr maxSeqno_
221 set list_($maxSeqno_) "$type $id"
222 return $maxSeqno_
223 }
224
225 FCAImportant instproc get { seq } {
226 $self instvar list_
227 if { [info exist list_($seq)] } {
228 return $list_($seq)
229 }
230 return ""
231 }
232
233
234 FCAImportant instproc obsolete { seqno } {
235 $self instvar list_ maxSeqno_
236 if { $seqno <= $maxSeqno_ } {
237 catch { unset list_($seqno) }
238 } elseif { $seqno == [expr $maxSeqno_ + 1] } {
239 incr maxSeqno_
240 }
241 }
242
243
244 FCAImportant instproc obsolete_specific { type id } {
245 $self instvar list_
246 foreach entry [array names list_ *] {
247 if { $list_($entry) == "$type $id" } {
248 unset list_($entry)
249 }
250 }
251 }
252
253
254 FCAImportant instproc is_obsolete { seqno } {
255 $self instvar maxSeqno_ list_
256 assert "$seqno <= $maxSeqno_"
257 if { $seqno <= $maxSeqno_ } {
258 if { ![info exists list_($seqno)] } {
259 return 1
260 }
261 }
262 return 0
263 }
264
265
266 FCAImportant instproc maxSeqno { } {
267 return [$self set maxSeqno_]
268 }
269
270
271 #FCAImportant instproc get { seqno typeVar idVar } {
272 #}
273
274
275 ################## Generic rcvr ###################
276 Class FCARcvr/Tcl -superclass FCARcvr
277 FCARcvr/Tcl instproc init { mgr srcId } {
278 $self next
279
280 $self set mgr_ $mgr
281 $self set srcId_ $srcId
282 $self set requests_ [new FCAAllRequests]
283 $self set important_ [new FCAImportant]
284 $self set repairRequest_ ""
285 $self set repairReply_ ""
286 $self set test_ 1
287 }
288
289
290 FCARcvr/Tcl instproc repair_request {} {
291 return [$self set repairRequest_]
292 }
293
294
295
296 FCARcvr/Tcl instproc get_requests { } {
297 return [$self set requests_]
298 }
299
300
301 FCARcvr/Tcl instproc srcId {} {
302 $self instvar srcId_
303 return $srcId_
304 }
305
306
307 FCARcvr/Tcl instproc obsolete_important { type id } {
308 [$self set important_] obsolete_specific $type $id
309 }
310
311
312 # return on whether need to reschedule
313 FCARcvr/Tcl instproc make_repair_request { isImportant sseq eseq } {
314 $self instvar repairRequest_
315 set newItem "$isImportant $sseq $eseq"
316 set needSched 0
317 if { $repairRequest_=="" } {
318 set needSched 1
319 set repairRequest_ [new FCARepairRequest/Tcl/Participant]
320 }
321 $repairRequest_ insert $newItem
322 return $needSched
323 }
324
325
326 # make participant repair reply
327 FCARcvr/Tcl instproc make_repair_reply {list} {
328 $self instvar repairReply_ requests_ important_ mgr_ srcId_
329
330 DbgOut "in make_repair_reply, list = $list"
331 DbgOut "FCARcvr/Tcl::make_repair_reply"
332 set needSched 0
333 foreach item $list {
334 set important [lindex $item 0]
335 set sseq [lindex $item 1]
336 set eseq [lindex $item 2]
337 DbgOut "FCARcvr/Tcl::make_repair_reply, this item is $item"
338
339
340 if { $important } {
341 for {set i $sseq} {$i <= $eseq} {incr i 1} {
342 # if 'i' is greater than the max we've seen, then we can't
343 # reply; otherwise, we either have the data or it's already
344 # obsolete
345
346 if { $i <= [$important_ maxSeqno] } {
347 # we know for sure that either we have the data or
348 # the data is obsolete
349
350 set item [$important_ get $i]
351
352 if { $repairReply_=={} } {
353 set needSched 1
354 set repairReply_ [new FCARepairReply/Tcl/Participant]
355 }
356
357 set fcaPkt [new FCA_Packet]
358 switch [lindex $item 0] {
359 cancel {
360 $fcaPkt set pktType PKT_FLOOR_CANCEL
361 $fcaPkt set seqno $i
362 $fcaPkt set requestId [lindex $item 1]
363 }
364 release {
365 not_implemented "release rreply"
366 }
367 "" {
368 # obsolete
369 $fcaPkt set pktType PKT_OBSOLETE
370 $fcaPkt set seqno $i
371 }
372 }
373
374 $repairReply_ insertReply $fcaPkt
375 }
376 }
377 } else {
378 for {set i $sseq} {$i <= $eseq} {incr i 1} {
379 DbgOut "it is floor request repair request"
380
381 if {[$requests_ have $i]} {
382 if {$repairReply_ == "" } {
383 set needSched 1
384 set repairReply_ [new FCARepairReply/Tcl/Participant]
385 }
386 DbgOut "about to insert the reply"
387
388 set request [$requests_ get $i]
389
390 set fcaPkt [new FCA_Packet]
391 $fcaPkt set pktType PKT_FLOOR_REQUEST
392 $fcaPkt set requestId [$request requestId]
393 $fcaPkt set comment [$request comment]
394 $fcaPkt set floors [$request floorTypes]
395 $fcaPkt set numFloors [llength [$fcaPkt set floors]]
396
397 $repairReply_ insertReply $fcaPkt
398
399 } elseif { [$requests_ is_canceled $i] } {
400 if {$repairReply_ == "" } {
401 set needSched 1
402 set repairReply_ [new FCARepairReply/Tcl/Participant]
403 }
404
405 set fcaPkt [new FCA_Packet]
406 $fcaPkt set pktType PKT_FLOOR_CANCEL
407 # FIXME: need to check whether this has been in the important
408 # list or not!
409 $fcaPkt set seqno 0
410 $fcaPkt set requestId $i
411
412 $repairReply_ insertReply $fcaPkt
413 }
414 }
415 }
416
417
418 #for {set i $sseq} {$i <= $eseq} {incr i 1} {
419 # if {$important} {
420 # set cancelitem [$important_ get $i]
421 # if { $cancelitem != "" } {
422 # # have the data to reply
423 # if {$repairReply_ == "" } {
424 # set needSched 1
425 # set repairReply_ [new FCARepairReply/Tcl/Participant]
426 # }
427 # $repairReply_ insertReply $important "$cancelitem $i"
428 # }
429 # } else {
430 # DbgOut "it is floor request repair request"
431 # if {[$requests_ have $i]} {
432 # if {$repairReply_ == "" } {
433 # DbgOut "needSched = 1"
434 # set needSched 1
435 # set repairReply_ [new FCARepairReply/Tcl/Participant]
436 # }
437 # DbgOut "about to insert the reply"
438 # $repairReply_ insertReply $important [$requests_ get $i]
439 # }
440 # }
441 #}
442 }
443
444 if {$needSched} {
445 $mgr_ sched_reply $repairReply_ $srcId_
446 DbgOut "FCARcvr/Tcl::make_repair_reply, repairReply ($repairReply_)\
447 the replies are [$repairReply_ pktReplies]"
448 }
449 }
450
451
452 #--- SRM callbacks ---#
453 # handling participant repair request
454 FCARcvr/Tcl instproc handle_request { fcaPkt } {
455 $self instvar repairRequest_ mgr_ srcId_
456 DbgOut "FCARcvr/Tcl::handle_request, about to make repair reply\
457 request list = [$fcaPkt set list]"
458 DbgOut "localSrcId [$mgr_ set localSrcId_], rcvr srcId_ ($srcId_)"
459 DbgOut "$$$$$$$$$$$$$$$$$$$$$$$$$$$"
460 if {$repairRequest_ != "" } {
461 if {[$repairRequest_ overlap $fcaPkt]} {
462 $repairRequest_ backoff
463 DbgOut "FCARcvr/Tcl::handle_request, repairRequest_ \
464 just backed off"
465 return
466 }
467 }
468 # if not backed off, see whether can reply:
469 DbgOut "FCARcvr/Tcl::handle_request, about to make repair reply\
470 request list = [$fcaPkt set list]"
471 $self make_repair_reply [$fcaPkt set list]
472 }
473
474
475
476 # handle participant repair reply
477 FCARcvr/Tcl instproc handle_reply { replyPkt } {
478 $self instvar mgr_ repairReply_ repairRequest_ requests_ important_
479
480 DbgOut "!!!!!!!!!!!!!!!!!!FCARcvr/Tcl::handle_reply, $$$$$$$$$$$$$$$$$"
481 if {$replyPkt == ""} {
482 DbgOut "FCARcvr/Tcl::handle_reply, replyPkt is empty"
483 return
484 }
485 set numReplies [$replyPkt set numReplies]
486 DbgOut "FCARcvr/Tcl::handle_reply, in replyPkt, numReplies = $numReplies"
487 set replies [$replyPkt set pktReplies]
488 DbgOut "FCARcvr/Tcl::handle_reply, replies obj = $replies"
489 foreach reply $replies {
490 if {$repairReply_ != ""} {
491 set canceled [$repairReply_ cancel_reply $reply]
492 if { [$repairReply_ set numReplies] <= 0 } {
493 # this reply's done
494 delete $repairReply_
495 DbgOut "Deleting repair reply!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
496 set repairReply_ ""
497 }
498
499 DbgOut "FCARcvr/Tcl handle_reply, canceled = $canceled"
500 continue
501 }
502
503 set replyPktType [$reply set pktType]
504 DbgOut "FCARcvr/Tcl::handle_reply, replyPktType -- $replyPktType"
505 switch $replyPktType {
506 "PKT_FLOOR_REQUEST" {
507 DbgOut "it is a floor request repair reply, \
508 FCARcvr/Tcl::handle_reply"
509 set replyRequestId [$reply set requestId]
510 if { [$requests_ dont_have $replyRequestId] } {
511 DbgOut "FCARcvr/Tcl::handle_reply, make repair for floor\
512 request"
513 $self handle_floor_request $reply
514
515 # adjust repair request after repairing
516 if {$repairRequest_!="" } {
517 $repairRequest_ gotReply 0 $replyRequestId
518 if { [$repairRequest_ set numRequests]==0 } {
519 delete $repairRequest_
520 DbgOut "Deleting repair request\
521 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
522 set repairRequest_ ""
523 }
524 }
525 }
526 }
527 "PKT_FLOOR_CANCEL" {
528 set replySeqno [$reply set seqno]
529 set maxCancelSeq [$important_ maxSeqno]
530 $self handle_floor_cancel $reply
531
532 #adjust repair request after repairing
533 if {$repairRequest_!="" } {
534 if { $replySeqno==0 } {
535 $repairRequest_ gotReply 0 [$reply set requestId]
536 } else {
537 $repairRequest_ gotReply 1 $replySeqno
538 }
539 if { [$repairRequest_ set numRequests]==0 } {
540 delete $repairRequest_
541 DbgOut "Deleting repair request\
542 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
543 set repairRequest_ ""
544 }
545 }
546 }
547 "PKT_FLOOR_RELEASE" {
548 not_implemented yet
549 DbgOut "FCARcvr/Tcl::parse_reply, release may not work!"
550 set replySeqno [$reply set seqno]
551 set maxCancelSeq [$important_ maxSeqno]
552 if {[$replySeqno == [expr $maxCancelSeq + 1]} {
553 $self handle_floor_release $reply
554
555 #adjust repair request after repairing
556 if {$repairRequest_!="" } {
557 $repairRequest_ gotReply 1 $replySeqno
558 if { [$repairRequest_ set numRequests]==0 } {
559 delete $repairRequest_
560 DbgOut "Deleting repair request\
561 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
562 set repairRequest_ ""
563 }
564 }
565 }
566 }
567 "PKT_OBSOLETE" {
568 set seqno [$reply set seqno]
569 $self instvar important_
570 $important_ obsolete $seqno
571
572 #adjust repair request after repairing
573 if {$repairRequest_!="" } {
574 $repairRequest_ gotReply 1 $seqno
575 if { [$repairRequest_ set numRequests]==0 } {
576 delete $repairRequest_
577 DbgOut "Deleting repair request\
578 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
579 set repairRequest_ ""
580 }
581 }
582 }
583 default {
584 DbgOut "FCARepairReply/Tcl/ParticipantFCARcvr/Tcl::\
585 cancel, wrong packet type"
586 }
587
588 }
589 # if {!$repaired} {
590 # adjust/cancel the repairReply_
591 # if no repair made by the incoming reply
592 # if {$repairReply_ != ""} {
593 # $repairReply_ cancel_reply $reply
594 # }
595 # }
596 }
597 }
598
599
600
601 # non-moderator rcvr will only make participant repair request
602 FCARcvr/Tcl instproc handle_SA { fcaPkt } {
603 $self instvar mgr_ srcId_ requests_ repairRequest_ important_
604
605 DbgOut "FCARcvr/Tcl::handle_SA, at participant rcvr ($srcId_), \
606 got session announcement from $srcId_:\
607 [$fcaPkt set maxRequestId] [$fcaPkt set maxImportantSeqno]"
608
609 DbgOut "FCARcvr/Tcl::handle_SA, localsrcId = [$mgr_ localSrcId]\
610 rcvr srcId = $srcId_"
611 if { [$mgr_ set localSrcId_] == $srcId_ } {
612 DbgOut "FCARcvr/Tcl::handle_SA, this is a local rcvr, shouldn't be \
613 handled here!!"
614 }
615 set fcd [$mgr_ fcDynamics]
616 set needSched 0
617 if { ![$fcd isRequestQFull] } {
618 set maxRequestId [$fcaPkt set maxRequestId]
619 set myMaxRequestId [$requests_ maxRequestId]
620 if { $maxRequestId > $myMaxRequestId } {
621 set qSpace [$fcd avail_requestQ_space]
622 set sseq [expr [$requests_ maxRequestId] + 1]
623 set eseq [expr $sseq + $qSpace]
624 if { $eseq > $maxRequestId } {
625 set eseq $maxRequestId
626 }
627 set newItem "0 $sseq $eseq"
628 if { $repairRequest_=="" } {
629 set needSched 1
630 set repairRequest_ [new FCARepairRequest/Tcl/Participant]
631 }
632 $repairRequest_ insert $newItem
633 }
634 }
635
636 set myImportantSeqno [$important_ maxSeqno]
637 set maxImportantSeqno [$fcaPkt set maxImportantSeqno]
638
639 if { $maxImportantSeqno > $myImportantSeqno } {
640 set newItem "1 [expr $myImportantSeqno+ 1] $maxImportantSeqno"
641 if { $repairRequest_=="" } {
642 set repairRequest_ [new FCARepairRequest/Tcl/Participant]
643 set needSched 1
644 }
645 $repairRequest_ insert $newItem
646 }
647 if {$needSched} {
648 DbgOut "handleSA: repairRequest = $repairRequest_"
649 $mgr_ sched_request $repairRequest_ $srcId_
650 DbgOut "repairRequest_(participant) ($repairRequest_) sent out"
651 DbgOut "numRequests = [$repairRequest_ set numRequests]\
652 list = [$repairRequest_ set list] \
653 pktType = [$repairRequest_ set pktType] "
654 # after 1000
655 }
656 }
657
658
659
660 FCARcvr/Tcl instproc recv { fcaPkt } {
661 set pktType [$fcaPkt set pktType]
662 switch $pktType {
663 "PKT_FLOOR_REQUEST" {
664 $self handle_floor_request $fcaPkt
665 }
666 "PKT_FLOOR_CANCEL" {
667 $self handle_floor_cancel $fcaPkt
668 }
669 "PKT_FLOOR_RELEASE" {
670 $self handle_floor_release $fcaPkt
671 }
672 default {
673 DbgOut "[$self srcId]: should not receive $pktType here!"
674 }
675 }
676 }
677
678
679 FCARcvr/Tcl instproc handle_floor_request { fcaPkt } {
680 $self instvar mgr_ srcId_ requests_ srcId_ test_
681
682 ###!! testing handle_sa and making repair request
683 # if {$test_} {
684 # set test_ 0
685 # DbgOut "rcvr $self ($srcId_) ignoring request [$fcaPkt set requestId]"
686 # return
687 # }
688 DbgOut "FCARcvr/Tcl handle_floor_request, about to rehandle the request"
689 set fcDynamics [$mgr_ fcDynamics]
690 if { [$fcDynamics isRequestQFull] } {
691 # for now, just ignore requests that arrive after the queue is full
692 return
693 }
694
695 set requestId [$fcaPkt set requestId]
696 if { ![$requests_ dont_have $requestId] } {
697 # we already have this request, or we don't care about it any more;
698 # ignore this packet
699 return
700 }
701
702 if { $requestId > [expr [$requests_ maxRequestId] + 1] } {
703 # this packet is out of order, reject it
704 DbgOut "Received out of order floor request"
705 return
706 }
707
708 # add this request to the list of requests I know of
709 set request [new FCAFloorRequest $srcId_ $requestId [$fcaPkt set floors] \
710 [$fcaPkt set comment]]
711 $requests_ got_request $requestId $request
712 $fcDynamics handle_floor_request $request
713 }
714
715
716 FCARcvr/Tcl instproc handle_floor_cancel { fcaPkt } {
717 $self instvar lastRequestId_ mgr_ requests_ important_ srcId_
718
719 ###!! testing handle_sa and making repair request
720 # DbgOut "rcvr $self ($srcId_) ignoring cancel [$fcaPkt set seqno] \
721 # for request [$fcaPkt set requestId]"
722 # return
723
724 set seqno [$fcaPkt set seqno]
725 if { $seqno > 0 && $seqno != [expr [$important_ maxSeqno] + 1] } {
726 # discard this packet, coz it's not in sequence
727 return
728 }
729
730 set requestId [$fcaPkt set requestId]
731 if { $requestId > [expr [$requests_ maxRequestId] + 1] } {
732 # ignore out of sequence request id
733 return
734 }
735
736 # I am trying to delete a (possibly) admitted request
737 # (or the next packet in sequence)
738
739 set fcDynamics [$mgr_ fcDynamics]
740 set needQueueUpdate 0
741 if { [$fcDynamics remove_admitted_request [$self srcId] $requestId] } {
742 # this request was in the admitted list i.e. we haven't received a
743 # queue update for it; we keep the cancel msg in our important_
744 # list until we hear from the moderator
745
746 set needQueueUpdate 1
747 if { $seqno > 0 } {
748 $important_ add cancel $requestId
749 }
750 } else {
751 # this requestId is not in the admitted list
752 # i.e. it's either not been admitted yet, or it has been admitted and
753 # removed: check for the cancel msg's seqno; if it's > 0, it means it
754 # had been admitted
755
756 if { $seqno > 0 } {
757 $important_ obsolete $seqno
758 }
759 }
760
761 $fcDynamics handle_floor_cancel $srcId_ $requestId $needQueueUpdate
762 $requests_ cancel $requestId
763 }
764
765
766 FCARcvr/Tcl instproc handle_floor_release { fcaPkt } {
767 $self instvar mgr_
768 set localIsModerator [$mgr_ localIsModerator]
769 set fcDynamics [$mgr_ fcDynamics]
770 set numUpdates [$fcaPkt set numUpdates]
771 set pktUpdates [$fcaPkt set pktUpdates]
772 if { $numUpdates != [llength $pktUpdates]} {
773 DbgOut "numfls != number of updates within pktGrants"
774 }
775 set needToUpdate 0
776 set releaseUpdates {}
777 set numReleased
778 foreach i $pktUpdates {
779 set grantSeqNo [$i set grantSeqno]
780 set srcId [$i set srcId]
781 set floorType [$i set floorType]
782 set instance [$i set floorInstance]
783 set requestId [$i set requestId]
784 set release [new FloorGrant $floorType $floorInstance $grantSeqNo $srcId $requestId]
785 set lastGrant [$fcDynamics getIsGrant $floorType $instance]
786 set bigger [expr $grantSeqNo > $lastGrant]
787 if {![$self GRIsStale $floorType $instance $grantSeqNo]} {
788 # if not a stale release
789 if {($localIsModerator) && (!$bigger) } {
790 # equal and is moderator
791 set success [$fcDynamics releaseHolder $floorType $instance $grantSeqNo]
792 if {$success} {
793 set needToUpdate 1
794 incr numFlReleased 1
795 set releaseUpdates [lappend $releaseUpdates $i]
796 } else {
797 DbgOut "releaseHolder failed"
798 }
799 }
800
801 }
802 }
803 if {$needToUpdate} {
804 # send release update
805 $fcDynamics incrStateNum
806 set newStateNum [$fcDynamics curStateNum]
807 set isGrant 0
808 set modRcvr [$mgr_ localRcvr]
809 $modRcvr sendGrantUpdate $isGrant $releaseUpdates $newStateNum
810 }
811 }
812
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.