blob: d51e34d6f762b0ad0b1ffb4dc51d58e351256713 [file] [log] [blame]
/*-------------------------------------------------------------------------
*
* cdb_backup_status.c
*
* Structures and functions to manipulate and access a linked list of
* structs that represent event notifications about the progress
* of a backup or restore operation.
*
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
*
*-------------------------------------------------------------------------
*/
#include "postgres_fe.h"
#include "pqexpbuffer.h"
#include "libpq-fe.h"
#include <time.h>
#include <pthread.h>
#include "cdb_dump_util.h"
#include "cdb_backup_status.h"
/*
* AddToStatusOpList: adds the StatusOp* to the end of the internal linked list in the StatusOpList*
*/
void
AddToStatusOpList(StatusOpList * pList, StatusOp * pOp)
{
pthread_mutex_lock(&pList->mGuard);
if (pList->pHead == NULL)
pList->pHead = pOp;
else
{
StatusOp *pLastOp = pList->pHead;
while (pLastOp->pNext != NULL)
pLastOp = pLastOp->pNext;
pLastOp->pNext = pOp;
}
pOp->pNext = NULL;
pthread_mutex_unlock(&pList->mGuard);
}
/*
* CreateStatusOp: mallocs memory for a new StatusOp, and
* initializes its fields based on the passed parameters.
*/
StatusOp *
CreateStatusOp(int TaskID, int TaskRC, const char *pszSuffix, const char *pszMsg)
{
StatusOp *pOp = (StatusOp *) calloc(1, sizeof(StatusOp));
if (pOp == NULL)
return pOp;
pOp->pNext = NULL;
pOp->TaskID = TaskID;
pOp->TaskRC = TaskRC;
pOp->pszSuffix = NULL;
if (pszSuffix != NULL)
pOp->pszSuffix = strdup(pszSuffix);
pOp->pszMsg = NULL;
if (pszMsg != NULL)
pOp->pszMsg = strdup(pszMsg);
return pOp;
}
/*
* CreateStatusOpList: mallocs memory for a new StatusOpList, and initializes its fields.
* Specifically, it initializes the ionternal linked list to NULL, and the mGuard mutex
* is initialized to have the recursive property.
*/
StatusOpList *
CreateStatusOpList(void)
{
pthread_mutexattr_t MyAttr;
StatusOpList *pList = (StatusOpList *) calloc(1, sizeof(StatusOpList));
if (pList == NULL)
return NULL;
pList->pHead = NULL;
pthread_mutexattr_init(&MyAttr);
pthread_mutexattr_settype(&MyAttr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&pList->mGuard, &MyAttr);
return pList;
}
/*
* DestroyStatusOpList: makes sure all the memory in the internal linked list is freed,
* destroys the mGaurd mutex, and frees the StatusOpList* .
*/
void
DestroyStatusOpList(StatusOpList * pList)
{
StatusOp *pHead;
if (pList == NULL)
return;
pthread_mutex_lock(&pList->mGuard);
pHead = pList->pHead;
while (pHead != NULL)
{
pList->pHead = pHead->pNext;
FreeStatusOp(pHead);
pHead = pList->pHead;
}
pthread_mutex_unlock(&pList->mGuard);
pthread_mutex_destroy(&pList->mGuard);
free(pList);
}
/*
* FreeStatusOp: frees all the memory alocated for the fields inside the StatusOp* and then
* frees the StatusOp*.
*/
void
FreeStatusOp(StatusOp * pOp)
{
if (pOp == NULL)
return;
if (pOp->pszSuffix != NULL)
free(pOp->pszSuffix);
if (pOp->pszMsg != NULL)
free(pOp->pszMsg);
free(pOp);
}
/*
* Lock: forces a lock of the mGuard mutex
*/
void
Lock(StatusOpList * pList)
{
pthread_mutex_lock(&pList->mGuard);
}
/*
* TakeFromStatusOpList: returns the head of the linked list, and makes the
* second element the new head.
*/
StatusOp *
TakeFromStatusOpList(StatusOpList * pList)
{
StatusOp *pOp;
pthread_mutex_lock(&pList->mGuard);
pOp = pList->pHead;
if (pOp != NULL)
{
pList->pHead = pOp->pNext;
}
pthread_mutex_unlock(&pList->mGuard);
return pOp;
}
/*
* Unlock: unlocls the mGuard mutex
*/
void
Unlock(StatusOpList * pList)
{
pthread_mutex_unlock(&pList->mGuard);
}