should be called only from timer process context, * else it's unsafe */
| 1016 | /* should be called only from timer process context, |
| 1017 | * else it's unsafe */ |
| 1018 | static void unlink_timers( struct cell *t ) |
| 1019 | { |
| 1020 | int i; |
| 1021 | int remove_fr, remove_retr; |
| 1022 | unsigned short set; |
| 1023 | |
| 1024 | remove_fr=0; remove_retr=0; |
| 1025 | |
| 1026 | /* first look if we need to remove timers and play with |
| 1027 | costly locks at all |
| 1028 | |
| 1029 | note that is_in_timer_list2 is unsafe but it does not |
| 1030 | hurt -- transaction is already dead (wait state) so that |
| 1031 | no one else will install a FR/RETR timer and it can only |
| 1032 | be removed from timer process itself -> it is safe to |
| 1033 | use it without any protection |
| 1034 | */ |
| 1035 | if (is_in_timer_list2(&t->uas.response.fr_timer)) remove_fr=1; |
| 1036 | else for (i=0; i<t->nr_of_outgoings; i++) |
| 1037 | if (is_in_timer_list2(&TM_BRANCH(t,i).request.fr_timer) |
| 1038 | || is_in_timer_list2(&TM_BRANCH(t,i).local_cancel.fr_timer)) { |
| 1039 | remove_fr=1; |
| 1040 | break; |
| 1041 | } |
| 1042 | if (is_in_timer_list2(&t->uas.response.retr_timer)) remove_retr=1; |
| 1043 | else for (i=0; i<t->nr_of_outgoings; i++) |
| 1044 | if (is_in_timer_list2(&TM_BRANCH(t,i).request.retr_timer) |
| 1045 | || is_in_timer_list2(&TM_BRANCH(t,i).local_cancel.retr_timer)) { |
| 1046 | remove_retr=1; |
| 1047 | break; |
| 1048 | } |
| 1049 | |
| 1050 | set = t->wait_tl.set; |
| 1051 | |
| 1052 | /* do what we have to do....*/ |
| 1053 | if (remove_retr) { |
| 1054 | /* RT_T1 lock is shared by all other RT timer |
| 1055 | lists -- we can safely lock just one |
| 1056 | */ |
| 1057 | lock(timertable[set].timers[RT_T1_TO_1].mutex); |
| 1058 | remove_timer_unsafe(&t->uas.response.retr_timer); |
| 1059 | for (i=0; i<t->nr_of_outgoings; i++) { |
| 1060 | remove_timer_unsafe(&TM_BRANCH(t,i).request.retr_timer); |
| 1061 | remove_timer_unsafe(&TM_BRANCH(t,i).local_cancel.retr_timer); |
| 1062 | } |
| 1063 | unlock(timertable[set].timers[RT_T1_TO_1].mutex); |
| 1064 | } |
| 1065 | if (remove_fr) { |
| 1066 | /* FR lock is shared by all other FR timer |
| 1067 | lists -- we can safely lock just one |
| 1068 | */ |
| 1069 | lock(timertable[set].timers[FR_TIMER_LIST].mutex); |
| 1070 | remove_timer_unsafe(&t->uas.response.fr_timer); |
| 1071 | for (i=0; i<t->nr_of_outgoings; i++) { |
| 1072 | remove_timer_unsafe(&TM_BRANCH(t,i).request.fr_timer); |
| 1073 | remove_timer_unsafe(&TM_BRANCH(t,i).local_cancel.fr_timer); |
| 1074 | } |
| 1075 | unlock(timertable[set].timers[FR_TIMER_LIST].mutex); |
no test coverage detected