| 193 | } |
| 194 | |
| 195 | static void destroy_plugin(struct plugin *p) |
| 196 | { |
| 197 | struct plugin_rpccall *call; |
| 198 | |
| 199 | list_del(&p->list); |
| 200 | |
| 201 | /* Terminate all pending RPC calls with an error. */ |
| 202 | list_for_each(&p->pending_rpccalls, call, list) { |
| 203 | was_pending(command_fail( |
| 204 | call->cmd, PLUGIN_TERMINATED, |
| 205 | "Plugin terminated before replying to RPC call.")); |
| 206 | } |
| 207 | /* Reset, so calls below don't try to fail it again! */ |
| 208 | list_head_init(&p->pending_rpccalls); |
| 209 | |
| 210 | /* If this was last one manifests were waiting for, handle deps */ |
| 211 | if (p->plugin_state == AWAITING_GETMANIFEST_RESPONSE) |
| 212 | check_plugins_manifests(p->plugins); |
| 213 | |
| 214 | /* Daemon shutdown overrules plugin's importance; aborts init checks */ |
| 215 | if (p->plugins->ld->state == LD_STATE_SHUTDOWN) { |
| 216 | /* But return if this was the last plugin! */ |
| 217 | if (list_empty(&p->plugins->plugins)) { |
| 218 | log_debug(p->plugins->ld->log, "io_break: %s", __func__); |
| 219 | io_break(destroy_plugin); |
| 220 | } |
| 221 | return; |
| 222 | } |
| 223 | |
| 224 | /* If this was the last one init was waiting for, handle cmd replies */ |
| 225 | if (p->plugin_state == AWAITING_INIT_RESPONSE) |
| 226 | check_plugins_initted(p->plugins); |
| 227 | |
| 228 | /* Now check if the dying plugin is important. */ |
| 229 | if (p->important) { |
| 230 | log_broken(p->log, |
| 231 | "Plugin marked as important, " |
| 232 | "shutting down lightningd!"); |
| 233 | lightningd_exit(p->plugins->ld, 1); |
| 234 | } |
| 235 | } |
| 236 | |
| 237 | static u32 file_checksum(struct lightningd *ld, const char *path) |
| 238 | { |
nothing calls this directly
no test coverage detected