/* * Copyright (c) 2019 TAOS Data, Inc. * * This program is free software: you can use, redistribute, and/or modify * it under the terms of the GNU Affero General Public License, version 3 * or later ("AGPL"), as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ #define _DEFAULT_SOURCE #include "tlog.h" #include "taoserror.h" #include "tstep.h" typedef struct { char * name; InitFp initFp; CleanupFp cleanupFp; } SStep; typedef struct SSteps { int32_t cursize; int32_t maxsize; SStep * steps; ReportFp reportFp; } SSteps; SSteps *taosStepInit(int32_t maxsize, ReportFp fp) { SSteps *steps = calloc(1, sizeof(SSteps)); if (steps == NULL) { terrno = TSDB_CODE_OUT_OF_MEMORY; return NULL; } steps->maxsize = maxsize; steps->cursize = 0; steps->steps = calloc(maxsize, sizeof(SStep)); steps->reportFp = fp; return steps; } int32_t taosStepAdd(struct SSteps *steps, char *name, InitFp initFp, CleanupFp cleanupFp) { if (steps == NULL) { terrno = TSDB_CODE_INVALID_PTR; return -1; } if (steps->cursize >= steps->maxsize) { uError("failed to add step since up to the maxsize"); terrno = TSDB_CODE_OUT_OF_RANGE; return -1; } SStep step = {.name = name, .initFp = initFp, .cleanupFp = cleanupFp}; steps->steps[steps->cursize++] = step; return 0; } static void taosStepCleanupImp(SSteps *steps, int32_t pos) { for (int32_t s = pos; s >= 0; s--) { SStep *step = steps->steps + s; uDebug("step:%s will cleanup", step->name); if (step->cleanupFp != NULL) { (*step->cleanupFp)(); } } } int32_t taosStepExec(SSteps *steps) { if (steps == NULL) { terrno = TSDB_CODE_INVALID_PTR; return -1; } for (int32_t s = 0; s < steps->cursize; s++) { SStep *step = steps->steps + s; if (step->initFp == NULL) continue; if (steps->reportFp != NULL) { (*steps->reportFp)(step->name, "start initialize"); } int32_t code = (*step->initFp)(); if (code != 0) { uDebug("step:%s will cleanup", step->name); taosStepCleanupImp(steps, s); return code; } uInfo("step:%s is initialized", step->name); if (steps->reportFp != NULL) { (*steps->reportFp)(step->name, "initialize completed"); } } return 0; } void taosStepCleanup(SSteps *steps) { if (steps == NULL) return; taosStepCleanupImp(steps, steps->cursize - 1); }