vnodeMgr.c 2.7 KB
Newer Older
H
Hongze Cheng 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
/*
 * Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
 *
 * 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 <http://www.gnu.org/licenses/>.
 */

#include "vnodeDef.h"

SVnodeMgr vnodeMgr = {.vnodeInitFlag = TD_MOD_UNINITIALIZED, .vnodeClearFlag = TD_MOD_UNCLEARD, .stop = false};

static void* loop(void* arg);

int vnodeInit(uint16_t nthreads) {
  if (TD_CHECK_AND_SET_MODE_INIT(&(vnodeMgr.vnodeInitFlag)) == TD_MOD_INITIALIZED) {
    return 0;
  }

  // Start commit handers
  if (nthreads > 0) {
    vnodeMgr.nthreads = nthreads;
    vnodeMgr.threads = (pthread_t*)calloc(nthreads, sizeof(pthread_t));
    if (vnodeMgr.threads == NULL) {
      return -1;
    }

    pthread_mutex_init(&(vnodeMgr.mutex), NULL);
    pthread_cond_init(&(vnodeMgr.hasTask), NULL);
    tDListInit(&(vnodeMgr.queue));

    for (uint16_t i = 0; i < nthreads; i++) {
      pthread_create(&(vnodeMgr.threads[i]), NULL, loop, NULL);
    }
  } else {
    // TODO: if no commit thread is set, then another mechanism should be
    // given. Otherwise, it is a false.
    ASSERT(0);
  }

  if (walInit() < 0) {
    return -1;
  }

  return 0;
}

void vnodeClear() {
  if (TD_CHECK_AND_SET_MOD_CLEAR(&(vnodeMgr.vnodeClearFlag)) == TD_MOD_CLEARD) {
    return;
  }

  walCleanUp();

  // Stop commit handler
  pthread_mutex_lock(&(vnodeMgr.mutex));
  vnodeMgr.stop = true;
  pthread_cond_broadcast(&(vnodeMgr.hasTask));
  pthread_mutex_unlock(&(vnodeMgr.mutex));

  for (uint16_t i = 0; i < vnodeMgr.nthreads; i++) {
    pthread_join(vnodeMgr.threads[i], NULL);
  }

  tfree(vnodeMgr.threads);
  pthread_cond_destroy(&(vnodeMgr.hasTask));
  pthread_mutex_destroy(&(vnodeMgr.mutex));
}

static void* loop(void* arg) {
  SVnodeTask* pTask;
  for (;;) {
    pthread_mutex_lock(&(vnodeMgr.mutex));
    for (;;) {
      pTask = TD_DLIST_HEAD(&(vnodeMgr.queue));
      if (pTask == NULL) {
        if (vnodeMgr.stop) {
          pthread_mutex_unlock(&(vnodeMgr.mutex));
          return NULL;
        } else {
          pthread_cond_wait(&(vnodeMgr.hasTask), &(vnodeMgr.mutex));
        }
      } else {
        tDListPop(&(vnodeMgr.queue), pTask);
        break;
      }
    }

    pthread_mutex_unlock(&(vnodeMgr.mutex));

    (*(pTask->execute))(pTask->arg);
  }

  return NULL;
}