fakebank_stop.c (5350B)
1 /* 2 This file is part of TALER 3 (C) 2016-2023 Taler Systems SA 4 5 TALER is free software; you can redistribute it and/or 6 modify it under the terms of the GNU General Public License 7 as published by the Free Software Foundation; either version 3, 8 or (at your option) any later version. 9 10 TALER is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public 16 License along with TALER; see the file COPYING. If not, 17 see <http://www.gnu.org/licenses/> 18 */ 19 /** 20 * @file bank-lib/fakebank_stop.c 21 * @brief library that fakes being a Taler bank for testcases 22 * @author Christian Grothoff <christian@grothoff.org> 23 */ 24 #include "taler/platform.h" 25 #include <pthread.h> 26 #include <poll.h> 27 #ifdef __linux__ 28 #include <sys/eventfd.h> 29 #endif 30 #include "taler/taler_fakebank_lib.h" 31 #include "taler/taler_bank_service.h" 32 #include "taler/taler_mhd_lib.h" 33 #include <gnunet/gnunet_mhd_compat.h> 34 #include "fakebank.h" 35 #include "fakebank_common_lp.h" 36 37 38 /** 39 * Helper function to free memory when finished. 40 * 41 * @param cls NULL 42 * @param key key of the account to free (ignored) 43 * @param val a `struct Account` to free. 44 */ 45 static enum GNUNET_GenericReturnValue 46 free_account (void *cls, 47 const struct GNUNET_HashCode *key, 48 void *val) 49 { 50 struct Account *account = val; 51 52 (void) cls; 53 (void) key; 54 GNUNET_assert (NULL == account->lp_head); 55 GNUNET_free (account->account_name); 56 GNUNET_free (account->receiver_name); 57 GNUNET_free (account->payto_uri); 58 GNUNET_free (account->password); 59 GNUNET_free (account); 60 return GNUNET_OK; 61 } 62 63 64 /** 65 * Helper function to free memory when finished. 66 * 67 * @param cls NULL 68 * @param key key of the operation to free (ignored) 69 * @param val a `struct WithdrawalOperation *` to free. 70 */ 71 static enum GNUNET_GenericReturnValue 72 free_withdraw_op (void *cls, 73 const struct GNUNET_ShortHashCode *key, 74 void *val) 75 { 76 struct WithdrawalOperation *wo = val; 77 78 (void) cls; 79 (void) key; 80 GNUNET_free (wo->amount); 81 GNUNET_free (wo); 82 return GNUNET_OK; 83 } 84 85 86 void 87 TALER_FAKEBANK_stop (struct TALER_FAKEBANK_Handle *h) 88 { 89 if (NULL != h->lp_task) 90 { 91 GNUNET_SCHEDULER_cancel (h->lp_task); 92 h->lp_task = NULL; 93 } 94 #if EPOLL_SUPPORT 95 if (NULL != h->mhd_rfd) 96 { 97 GNUNET_NETWORK_socket_free_memory_only_ (h->mhd_rfd); 98 h->mhd_rfd = NULL; 99 } 100 #endif 101 #ifdef __linux__ 102 if (-1 != h->lp_event) 103 #else 104 if (-1 != h->lp_event_in && -1 != h->lp_event_out) 105 #endif 106 { 107 uint64_t val = 1; 108 void *ret; 109 struct LongPoller *lp; 110 111 GNUNET_assert (0 == 112 pthread_mutex_lock (&h->big_lock)); 113 h->in_shutdown = true; 114 while (NULL != (lp = GNUNET_CONTAINER_heap_remove_root (h->lp_heap))) 115 TALER_FAKEBANK_lp_trigger_ (lp); 116 GNUNET_assert (0 == 117 pthread_mutex_unlock (&h->big_lock)); 118 #ifdef __linux__ 119 GNUNET_break (sizeof (val) == 120 write (h->lp_event, 121 &val, 122 sizeof (val))); 123 #else 124 GNUNET_break (sizeof (val) == 125 write (h->lp_event_in, 126 &val, 127 sizeof (val))); 128 #endif 129 GNUNET_break (0 == 130 pthread_join (h->lp_thread, 131 &ret)); 132 GNUNET_break (NULL == ret); 133 #ifdef __linux__ 134 GNUNET_break (0 == close (h->lp_event)); 135 h->lp_event = -1; 136 #else 137 GNUNET_break (0 == close (h->lp_event_in)); 138 GNUNET_break (0 == close (h->lp_event_out)); 139 h->lp_event_in = -1; 140 h->lp_event_out = -1; 141 #endif 142 } 143 else 144 { 145 struct LongPoller *lp; 146 147 while (NULL != (lp = GNUNET_CONTAINER_heap_remove_root (h->lp_heap))) 148 TALER_FAKEBANK_lp_trigger_ (lp); 149 } 150 if (NULL != h->mhd_bank) 151 { 152 MHD_stop_daemon (h->mhd_bank); 153 h->mhd_bank = NULL; 154 } 155 if (NULL != h->mhd_task) 156 { 157 GNUNET_SCHEDULER_cancel (h->mhd_task); 158 h->mhd_task = NULL; 159 } 160 if (NULL != h->accounts) 161 { 162 GNUNET_CONTAINER_multihashmap_iterate (h->accounts, 163 &free_account, 164 NULL); 165 GNUNET_CONTAINER_multihashmap_destroy (h->accounts); 166 } 167 if (NULL != h->wops) 168 { 169 GNUNET_CONTAINER_multishortmap_iterate (h->wops, 170 &free_withdraw_op, 171 NULL); 172 GNUNET_CONTAINER_multishortmap_destroy (h->wops); 173 } 174 GNUNET_CONTAINER_multihashmap_destroy (h->uuid_map); 175 GNUNET_CONTAINER_multipeermap_destroy (h->rpubs); 176 GNUNET_CONTAINER_heap_destroy (h->lp_heap); 177 GNUNET_assert (0 == 178 pthread_mutex_destroy (&h->big_lock)); 179 GNUNET_assert (0 == 180 pthread_mutex_destroy (&h->uuid_map_lock)); 181 GNUNET_assert (0 == 182 pthread_mutex_destroy (&h->accounts_lock)); 183 GNUNET_assert (0 == 184 pthread_mutex_destroy (&h->rpubs_lock)); 185 for (uint64_t i = 0; i<h->ram_limit; i++) 186 GNUNET_free (h->transactions[i]); 187 GNUNET_free (h->transactions); 188 GNUNET_free (h->my_baseurl); 189 GNUNET_free (h->currency); 190 GNUNET_free (h->exchange_url); 191 GNUNET_free (h->hostname); 192 GNUNET_free (h); 193 }