mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2024-12-12 10:04:14 +02:00
Replace OBJECT_DEFINE_GET() with *Pub struct pattern.
This macro was originally intended to simplify the creation of simple getters but it has been superseded by the pattern introduced in 79a2d02c
.
Remove instances of OBJECT_DEFINE_GET() to avoid confusion with the new pattern.
This commit is contained in:
parent
b715c70b46
commit
cc85c4f03d
@ -24,15 +24,13 @@ Object type
|
||||
***********************************************************************************************************************************/
|
||||
struct HttpClient
|
||||
{
|
||||
HttpClientPub pub; // Publicly accessible variables
|
||||
MemContext *memContext; // Mem context
|
||||
TimeMSec timeout; // Request timeout
|
||||
IoClient *ioClient; // Io client (e.g. TLS or socket client)
|
||||
|
||||
List *sessionReuseList; // List of HTTP sessions that can be reused
|
||||
};
|
||||
|
||||
OBJECT_DEFINE_GET(Timeout, const, HTTP_CLIENT, TimeMSec, timeout);
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
HttpClient *
|
||||
httpClientNew(IoClient *ioClient, TimeMSec timeout)
|
||||
@ -52,8 +50,11 @@ httpClientNew(IoClient *ioClient, TimeMSec timeout)
|
||||
|
||||
*this = (HttpClient)
|
||||
{
|
||||
.pub =
|
||||
{
|
||||
.timeout = timeout,
|
||||
},
|
||||
.memContext = MEM_CONTEXT_NEW(),
|
||||
.timeout = timeout,
|
||||
.ioClient = ioClient,
|
||||
.sessionReuseList = lstNewP(sizeof(HttpSession *)),
|
||||
};
|
||||
@ -121,5 +122,5 @@ httpClientToLog(const HttpClient *this)
|
||||
{
|
||||
return strNewFmt(
|
||||
"{ioClient: %s, reusable: %u, timeout: %" PRIu64"}", strZ(ioClientToLog(this->ioClient)), lstSize(this->sessionReuseList),
|
||||
this->timeout);
|
||||
httpClientTimeout(this));
|
||||
}
|
||||
|
@ -19,9 +19,6 @@ completes and tries to call httpClientReuse() on an HttpClient that has been fre
|
||||
/***********************************************************************************************************************************
|
||||
Object type
|
||||
***********************************************************************************************************************************/
|
||||
#define HTTP_CLIENT_TYPE HttpClient
|
||||
#define HTTP_CLIENT_PREFIX httpClient
|
||||
|
||||
typedef struct HttpClient HttpClient;
|
||||
|
||||
#include "common/io/client.h"
|
||||
@ -47,6 +44,21 @@ Constructors
|
||||
***********************************************************************************************************************************/
|
||||
HttpClient *httpClientNew(IoClient *ioClient, TimeMSec timeout);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Getters/Setters
|
||||
***********************************************************************************************************************************/
|
||||
typedef struct HttpClientPub
|
||||
{
|
||||
TimeMSec timeout; // Request timeout
|
||||
} HttpClientPub;
|
||||
|
||||
__attribute__((always_inline)) static inline TimeMSec
|
||||
httpClientTimeout(const HttpClient *this)
|
||||
{
|
||||
ASSERT_INLINE(this != NULL);
|
||||
return ((const HttpClientPub *)this)->timeout;
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Functions
|
||||
***********************************************************************************************************************************/
|
||||
@ -56,11 +68,6 @@ HttpSession *httpClientOpen(HttpClient *this);
|
||||
// Request/response finished cleanly so session can be reused
|
||||
void httpClientReuse(HttpClient *this, HttpSession *session);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Getters/Setters
|
||||
***********************************************************************************************************************************/
|
||||
TimeMSec httpClientTimeout(const HttpClient *this);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Macros for function logging
|
||||
***********************************************************************************************************************************/
|
||||
|
@ -44,12 +44,9 @@ Object type
|
||||
***********************************************************************************************************************************/
|
||||
struct HttpRequest
|
||||
{
|
||||
HttpRequestPub pub; // Publicly accessible variables
|
||||
MemContext *memContext; // Mem context
|
||||
HttpClient *client; // HTTP client
|
||||
const String *verb; // HTTP verb (GET, POST, etc.)
|
||||
const String *path; // HTTP path
|
||||
const HttpQuery *query; // HTTP query
|
||||
const HttpHeader *header; // HTTP headers
|
||||
const Buffer *content; // HTTP content
|
||||
|
||||
HttpSession *session; // Session for async requests
|
||||
@ -58,11 +55,6 @@ struct HttpRequest
|
||||
OBJECT_DEFINE_MOVE(HTTP_REQUEST);
|
||||
OBJECT_DEFINE_FREE(HTTP_REQUEST);
|
||||
|
||||
OBJECT_DEFINE_GET(Verb, const, HTTP_REQUEST, const String *, verb);
|
||||
OBJECT_DEFINE_GET(Path, const, HTTP_REQUEST, const String *, path);
|
||||
OBJECT_DEFINE_GET(Query, const, HTTP_REQUEST, const HttpQuery *, query);
|
||||
OBJECT_DEFINE_GET(Header, const, HTTP_REQUEST, const HttpHeader *, header);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Process the request
|
||||
***********************************************************************************************************************************/
|
||||
@ -111,17 +103,19 @@ httpRequestProcess(HttpRequest *this, bool waitForResponse, bool contentCache)
|
||||
String *requestStr =
|
||||
strNewFmt(
|
||||
"%s %s%s%s " HTTP_VERSION CRLF_Z HTTP_HEADER_USER_AGENT ":" PROJECT_NAME "/" PROJECT_VERSION CRLF_Z,
|
||||
strZ(this->verb), strZ(this->path), this->query == NULL ? "" : "?",
|
||||
this->query == NULL ? "" : strZ(httpQueryRenderP(this->query)));
|
||||
strZ(httpRequestVerb(this)), strZ(httpRequestPath(this)), httpRequestQuery(this) == NULL ? "" : "?",
|
||||
httpRequestQuery(this) == NULL ? "" : strZ(httpQueryRenderP(httpRequestQuery(this))));
|
||||
|
||||
// Add headers
|
||||
const StringList *headerList = httpHeaderList(this->header);
|
||||
const StringList *headerList = httpHeaderList(httpRequestHeader(this));
|
||||
|
||||
for (unsigned int headerIdx = 0; headerIdx < strLstSize(headerList); headerIdx++)
|
||||
{
|
||||
const String *headerKey = strLstGet(headerList, headerIdx);
|
||||
|
||||
strCatFmt(requestStr, "%s:%s" CRLF_Z, strZ(headerKey), strZ(httpHeaderGet(this->header, headerKey)));
|
||||
strCatFmt(
|
||||
requestStr, "%s:%s" CRLF_Z, strZ(headerKey),
|
||||
strZ(httpHeaderGet(httpRequestHeader(this), headerKey)));
|
||||
}
|
||||
|
||||
// Add blank line to end of headers and write the request as a buffer so secrets do not show up in logs
|
||||
@ -143,7 +137,7 @@ httpRequestProcess(HttpRequest *this, bool waitForResponse, bool contentCache)
|
||||
// Wait for response
|
||||
if (waitForResponse)
|
||||
{
|
||||
result = httpResponseNew(session, this->verb, contentCache);
|
||||
result = httpResponseNew(session, httpRequestVerb(this), contentCache);
|
||||
|
||||
// Retry when response code is 5xx. These errors generally represent a server error for a request that
|
||||
// looks valid. There are a few errors that might be permanently fatal but they are rare and it seems best
|
||||
@ -206,12 +200,15 @@ httpRequestNew(HttpClient *client, const String *verb, const String *path, HttpR
|
||||
|
||||
*this = (HttpRequest)
|
||||
{
|
||||
.pub =
|
||||
{
|
||||
.verb = strDup(verb),
|
||||
.path = strDup(path),
|
||||
.query = httpQueryDupP(param.query),
|
||||
.header = param.header == NULL ? httpHeaderNew(NULL) : httpHeaderDup(param.header, NULL),
|
||||
},
|
||||
.memContext = MEM_CONTEXT_NEW(),
|
||||
.client = client,
|
||||
.verb = strDup(verb),
|
||||
.path = strDup(path),
|
||||
.query = httpQueryDupP(param.query),
|
||||
.header = param.header == NULL ? httpHeaderNew(NULL) : httpHeaderDup(param.header, NULL),
|
||||
.content = param.content == NULL ? NULL : bufDup(param.content),
|
||||
};
|
||||
|
||||
@ -260,13 +257,13 @@ httpRequestError(const HttpRequest *this, HttpResponse *response)
|
||||
// Output path/query
|
||||
strCatZ(error, ":\n*** Path/Query ***:");
|
||||
|
||||
strCatFmt(error, "\n%s", strZ(this->path));
|
||||
strCatFmt(error, "\n%s", strZ(httpRequestPath(this)));
|
||||
|
||||
if (this->query != NULL)
|
||||
strCatFmt(error, "?%s", strZ(httpQueryRenderP(this->query, .redact = true)));
|
||||
if (httpRequestQuery(this) != NULL)
|
||||
strCatFmt(error, "?%s", strZ(httpQueryRenderP(httpRequestQuery(this), .redact = true)));
|
||||
|
||||
// Output request headers
|
||||
const StringList *requestHeaderList = httpHeaderList(this->header);
|
||||
const StringList *requestHeaderList = httpHeaderList(httpRequestHeader(this));
|
||||
|
||||
if (!strLstEmpty(requestHeaderList))
|
||||
{
|
||||
@ -278,7 +275,7 @@ httpRequestError(const HttpRequest *this, HttpResponse *response)
|
||||
|
||||
strCatFmt(
|
||||
error, "\n%s: %s", strZ(key),
|
||||
httpHeaderRedact(this->header, key) ? "<redacted>" : strZ(httpHeaderGet(this->header, key)));
|
||||
httpHeaderRedact(httpRequestHeader(this), key) ? "<redacted>" : strZ(httpHeaderGet(httpRequestHeader(this), key)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -312,7 +309,7 @@ String *
|
||||
httpRequestToLog(const HttpRequest *this)
|
||||
{
|
||||
return strNewFmt(
|
||||
"{verb: %s, path: %s, query: %s, header: %s, contentSize: %zu}", strZ(this->verb), strZ(this->path),
|
||||
this->query == NULL ? "null" : strZ(httpQueryToLog(this->query)), strZ(httpHeaderToLog(this->header)),
|
||||
this->content == NULL ? 0 : bufUsed(this->content));
|
||||
"{verb: %s, path: %s, query: %s, header: %s, contentSize: %zu}", strZ(httpRequestVerb(this)), strZ(httpRequestPath(this)),
|
||||
httpRequestQuery(this) == NULL ? "null" : strZ(httpQueryToLog(httpRequestQuery(this))),
|
||||
strZ(httpHeaderToLog(httpRequestHeader(this))), this->content == NULL ? 0 : bufUsed(this->content));
|
||||
}
|
||||
|
@ -77,6 +77,49 @@ typedef struct HttpRequestNewParam
|
||||
|
||||
HttpRequest *httpRequestNew(HttpClient *client, const String *verb, const String *path, HttpRequestNewParam param);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Getters/Setters
|
||||
***********************************************************************************************************************************/
|
||||
typedef struct HttpRequestPub
|
||||
{
|
||||
const String *verb; // HTTP verb (GET, POST, etc.)
|
||||
const String *path; // HTTP path
|
||||
const HttpQuery *query; // HTTP query
|
||||
const HttpHeader *header; // HTTP headers
|
||||
} HttpRequestPub;
|
||||
|
||||
// Request path
|
||||
__attribute__((always_inline)) static inline const String *
|
||||
httpRequestPath(const HttpRequest *this)
|
||||
{
|
||||
ASSERT_INLINE(this != NULL);
|
||||
return ((const HttpRequestPub *)this)->path;
|
||||
}
|
||||
|
||||
// Request query
|
||||
__attribute__((always_inline)) static inline const HttpQuery *
|
||||
httpRequestQuery(const HttpRequest *this)
|
||||
{
|
||||
ASSERT_INLINE(this != NULL);
|
||||
return ((const HttpRequestPub *)this)->query;
|
||||
}
|
||||
|
||||
// Request headers
|
||||
__attribute__((always_inline)) static inline const HttpHeader *
|
||||
httpRequestHeader(const HttpRequest *this)
|
||||
{
|
||||
ASSERT_INLINE(this != NULL);
|
||||
return ((const HttpRequestPub *)this)->header;
|
||||
}
|
||||
|
||||
// Request verb
|
||||
__attribute__((always_inline)) static inline const String *
|
||||
httpRequestVerb(const HttpRequest *this)
|
||||
{
|
||||
ASSERT_INLINE(this != NULL);
|
||||
return ((const HttpRequestPub *)this)->verb;
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Functions
|
||||
***********************************************************************************************************************************/
|
||||
@ -89,21 +132,6 @@ void httpRequestError(const HttpRequest *this, HttpResponse *response) __attribu
|
||||
// Move to a new parent mem context
|
||||
HttpRequest *httpRequestMove(HttpRequest *this, MemContext *parentNew);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Getters/Setters
|
||||
***********************************************************************************************************************************/
|
||||
// Request verb
|
||||
const String *httpRequestVerb(const HttpRequest *this);
|
||||
|
||||
// Request path
|
||||
const String *httpRequestPath(const HttpRequest *this);
|
||||
|
||||
// Request query
|
||||
const HttpQuery *httpRequestQuery(const HttpRequest *this);
|
||||
|
||||
// Request headers
|
||||
const HttpHeader *httpRequestHeader(const HttpRequest *this);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Destructor
|
||||
***********************************************************************************************************************************/
|
||||
|
@ -33,14 +33,10 @@ Object type
|
||||
***********************************************************************************************************************************/
|
||||
struct HttpResponse
|
||||
{
|
||||
HttpResponsePub pub; // Publicly accessible variables
|
||||
MemContext *memContext; // Mem context
|
||||
|
||||
HttpSession *session; // HTTP session
|
||||
IoRead *contentRead; // Read interface for response content
|
||||
|
||||
unsigned int code; // Response code (e.g. 200, 404)
|
||||
String *reason; // Response reason e.g. (OK, Not Found)
|
||||
HttpHeader *header; // Response headers
|
||||
|
||||
bool contentChunked; // Is the response content chunked?
|
||||
uint64_t contentSize; // Content size (ignored for chunked)
|
||||
@ -54,11 +50,6 @@ struct HttpResponse
|
||||
OBJECT_DEFINE_MOVE(HTTP_RESPONSE);
|
||||
OBJECT_DEFINE_FREE(HTTP_RESPONSE);
|
||||
|
||||
OBJECT_DEFINE_GET(IoRead, , HTTP_RESPONSE, IoRead *, contentRead);
|
||||
OBJECT_DEFINE_GET(Code, const, HTTP_RESPONSE, unsigned int, code);
|
||||
OBJECT_DEFINE_GET(Header, const, HTTP_RESPONSE, const HttpHeader *, header);
|
||||
OBJECT_DEFINE_GET(Reason, const, HTTP_RESPONSE, const String *, reason);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
When response is done close/reuse the connection
|
||||
***********************************************************************************************************************************/
|
||||
@ -224,9 +215,12 @@ httpResponseNew(HttpSession *session, const String *verb, bool contentCache)
|
||||
|
||||
*this = (HttpResponse)
|
||||
{
|
||||
.pub =
|
||||
{
|
||||
.header = httpHeaderNew(NULL),
|
||||
},
|
||||
.memContext = MEM_CONTEXT_NEW(),
|
||||
.session = httpSessionMove(session, memContextCurrent()),
|
||||
.header = httpHeaderNew(NULL),
|
||||
};
|
||||
|
||||
MEM_CONTEXT_TEMP_BEGIN()
|
||||
@ -261,12 +255,12 @@ httpResponseNew(HttpSession *session, const String *verb, bool contentCache)
|
||||
if (spacePos != 3)
|
||||
THROW_FMT(FormatError, "response status '%s' must have a space after the status code", strZ(status));
|
||||
|
||||
this->code = cvtZToUInt(strZ(strSubN(status, 0, (size_t)spacePos)));
|
||||
this->pub.code = cvtZToUInt(strZ(strSubN(status, 0, (size_t)spacePos)));
|
||||
|
||||
// Read reason phrase. A missing reason phrase will be represented as an empty string.
|
||||
MEM_CONTEXT_BEGIN(this->memContext)
|
||||
{
|
||||
this->reason = strSub(status, (size_t)spacePos + 1);
|
||||
this->pub.reason = strSub(status, (size_t)spacePos + 1);
|
||||
}
|
||||
MEM_CONTEXT_END();
|
||||
|
||||
@ -289,7 +283,7 @@ httpResponseNew(HttpSession *session, const String *verb, bool contentCache)
|
||||
String *headerKey = strLower(strTrim(strSubN(header, 0, (size_t)colonPos)));
|
||||
String *headerValue = strTrim(strSub(header, (size_t)colonPos + 1));
|
||||
|
||||
httpHeaderAdd(this->header, headerKey, headerValue);
|
||||
httpHeaderAdd(this->pub.header, headerKey, headerValue);
|
||||
|
||||
// Read transfer encoding (only chunked is supported)
|
||||
if (strEq(headerKey, HTTP_HEADER_TRANSFER_ENCODING_STR))
|
||||
@ -336,8 +330,8 @@ httpResponseNew(HttpSession *session, const String *verb, bool contentCache)
|
||||
// rather than also checking if the io object exists.
|
||||
MEM_CONTEXT_BEGIN(this->memContext)
|
||||
{
|
||||
this->contentRead = ioReadNewP(this, .eof = httpResponseEof, .read = httpResponseRead);
|
||||
ioReadOpen(this->contentRead);
|
||||
this->pub.contentRead = ioReadNewP(this, .eof = httpResponseEof, .read = httpResponseRead);
|
||||
ioReadOpen(httpResponseIoRead(this));
|
||||
}
|
||||
MEM_CONTEXT_END();
|
||||
|
||||
@ -393,19 +387,6 @@ httpResponseContent(HttpResponse *this)
|
||||
FUNCTION_TEST_RETURN(this->content);
|
||||
}
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
bool
|
||||
httpResponseCodeOk(const HttpResponse *this)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(HTTP_RESPONSE, this);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(this->code / 100 == 2);
|
||||
}
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
String *
|
||||
httpResponseToLog(const HttpResponse *this)
|
||||
@ -413,7 +394,7 @@ httpResponseToLog(const HttpResponse *this)
|
||||
return strNewFmt(
|
||||
"{code: %u, reason: %s, header: %s, contentChunked: %s, contentSize: %" PRIu64 ", contentRemaining: %" PRIu64
|
||||
", closeOnContentEof: %s, contentExists: %s, contentEof: %s, contentCached: %s}",
|
||||
this->code, strZ(this->reason), strZ(httpHeaderToLog(this->header)), cvtBoolToConstZ(this->contentChunked),
|
||||
this->contentSize, this->contentRemaining, cvtBoolToConstZ(this->closeOnContentEof), cvtBoolToConstZ(this->contentExists),
|
||||
cvtBoolToConstZ(this->contentEof), cvtBoolToConstZ(this->content != NULL));
|
||||
httpResponseCode(this), strZ(httpResponseReason(this)), strZ(httpHeaderToLog(httpResponseHeader(this))),
|
||||
cvtBoolToConstZ(this->contentChunked), this->contentSize, this->contentRemaining, cvtBoolToConstZ(this->closeOnContentEof),
|
||||
cvtBoolToConstZ(this->contentExists), cvtBoolToConstZ(this->contentEof), cvtBoolToConstZ(this->content != NULL));
|
||||
}
|
||||
|
@ -31,11 +31,59 @@ Constructors
|
||||
***********************************************************************************************************************************/
|
||||
HttpResponse *httpResponseNew(HttpSession *session, const String *verb, bool contentCache);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Getters/Setters
|
||||
***********************************************************************************************************************************/
|
||||
typedef struct HttpResponsePub
|
||||
{
|
||||
IoRead *contentRead; // Read interface for response content
|
||||
unsigned int code; // Response code (e.g. 200, 404)
|
||||
HttpHeader *header; // Response headers
|
||||
String *reason; // Response reason e.g. (OK, Not Found)
|
||||
} HttpResponsePub;
|
||||
|
||||
// Read interface used to get the response content. This is intended for reading content that may be very large and will not be held
|
||||
// in memory all at once. If the content must be loaded completely for processing (e.g. XML) then httpResponseContent() is simpler.
|
||||
__attribute__((always_inline)) static inline IoRead *
|
||||
httpResponseIoRead(HttpResponse *this)
|
||||
{
|
||||
ASSERT_INLINE(this != NULL);
|
||||
return ((const HttpResponsePub *)this)->contentRead;
|
||||
}
|
||||
|
||||
// Response code
|
||||
__attribute__((always_inline)) static inline unsigned int
|
||||
httpResponseCode(const HttpResponse *this)
|
||||
{
|
||||
ASSERT_INLINE(this != NULL);
|
||||
return ((const HttpResponsePub *)this)->code;
|
||||
}
|
||||
|
||||
// Response headers
|
||||
__attribute__((always_inline)) static inline const HttpHeader *
|
||||
httpResponseHeader(const HttpResponse *this)
|
||||
{
|
||||
ASSERT_INLINE(this != NULL);
|
||||
return ((const HttpResponsePub *)this)->header;
|
||||
}
|
||||
|
||||
// Response reason
|
||||
__attribute__((always_inline)) static inline const String *
|
||||
httpResponseReason(const HttpResponse *this)
|
||||
{
|
||||
ASSERT_INLINE(this != NULL);
|
||||
return ((const HttpResponsePub *)this)->reason;
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Functions
|
||||
***********************************************************************************************************************************/
|
||||
// Is this response code OK, i.e. 2XX?
|
||||
bool httpResponseCodeOk(const HttpResponse *this);
|
||||
__attribute__((always_inline)) static inline bool
|
||||
httpResponseCodeOk(const HttpResponse *this)
|
||||
{
|
||||
return httpResponseCode(this) / 100 == 2;
|
||||
}
|
||||
|
||||
// Fetch all response content. Content will be cached so it can be retrieved again without additional cost.
|
||||
const Buffer *httpResponseContent(HttpResponse *this);
|
||||
@ -43,25 +91,6 @@ const Buffer *httpResponseContent(HttpResponse *this);
|
||||
// Move to a new parent mem context
|
||||
HttpResponse *httpResponseMove(HttpResponse *this, MemContext *parentNew);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Getters/Setters
|
||||
***********************************************************************************************************************************/
|
||||
// Is the response still being read?
|
||||
bool httpResponseBusy(const HttpResponse *this);
|
||||
|
||||
// Read interface used to get the response content. This is intended for reading content that may be very large and will not be held
|
||||
// in memory all at once. If the content must be loaded completely for processing (e.g. XML) then httpResponseContent() is simpler.
|
||||
IoRead *httpResponseIoRead(HttpResponse *this);
|
||||
|
||||
// Response code
|
||||
unsigned int httpResponseCode(const HttpResponse *this);
|
||||
|
||||
// Response headers
|
||||
const HttpHeader *httpResponseHeader(const HttpResponse *this);
|
||||
|
||||
// Response reason
|
||||
const String *httpResponseReason(const HttpResponse *this);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Destructor
|
||||
***********************************************************************************************************************************/
|
||||
|
@ -34,27 +34,6 @@ Create a local "this" variable of the correct type from a THIS_VOID parameter
|
||||
***********************************************************************************************************************************/
|
||||
#define THIS(type) type *this = thisVoid
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Define a function used to get an object member variable.
|
||||
|
||||
If the object type/prefix is "Object"/"object" then the macro:
|
||||
|
||||
OBJECT_DEFINE_GET(Size, const, OBJECT, size_t, size);
|
||||
|
||||
will define the function as:
|
||||
|
||||
size_t objectSize(const Object *this)
|
||||
|
||||
No function logging in required because no functions can be called which means no errors can be thrown.
|
||||
***********************************************************************************************************************************/
|
||||
#define OBJECT_DEFINE_GET(name, objectQualifier, objectMacro, returnType, objectMember) \
|
||||
returnType \
|
||||
GLUE(objectMacro##_PREFIX, name)(objectQualifier objectMacro##_TYPE *this) \
|
||||
{ \
|
||||
ASSERT(this != NULL); \
|
||||
return this->objectMember; \
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Define a function used by the caller to move an object from one context to another
|
||||
|
||||
|
@ -14,16 +14,14 @@ Object type
|
||||
***********************************************************************************************************************************/
|
||||
struct Wait
|
||||
{
|
||||
WaitPub pub; // Publicly accessible variables
|
||||
MemContext *memContext; // Context that contains the wait handler
|
||||
TimeMSec waitTime; // Total time to wait (in usec)
|
||||
TimeMSec remainTime; // Wait time remaining (in usec)
|
||||
TimeMSec sleepTime; // Next sleep time (in usec)
|
||||
TimeMSec sleepPrevTime; // Previous time slept (in usec)
|
||||
TimeMSec beginTime; // Time the wait began (in epoch usec)
|
||||
};
|
||||
|
||||
OBJECT_DEFINE_GET(Remaining, const, WAIT, TimeMSec, remainTime);
|
||||
|
||||
OBJECT_DEFINE_FREE(WAIT);
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
@ -46,9 +44,12 @@ waitNew(TimeMSec waitTime)
|
||||
|
||||
*this = (Wait)
|
||||
{
|
||||
.pub =
|
||||
{
|
||||
.remainTime = waitTime,
|
||||
},
|
||||
.memContext = MEM_CONTEXT_NEW(),
|
||||
.waitTime = waitTime,
|
||||
.remainTime = waitTime,
|
||||
};
|
||||
|
||||
// Calculate first sleep time -- start with 1/10th of a second for anything >= 1 second
|
||||
@ -100,7 +101,7 @@ waitMore(Wait *this)
|
||||
// Store new sleep times
|
||||
this->sleepPrevTime = this->sleepTime;
|
||||
this->sleepTime = sleepNextTime;
|
||||
this->remainTime = this->waitTime - elapsedTime;
|
||||
this->pub.remainTime = this->waitTime - elapsedTime;
|
||||
}
|
||||
// Else set sleep to zero so next call will return false
|
||||
else
|
||||
|
@ -19,18 +19,28 @@ Constructors
|
||||
***********************************************************************************************************************************/
|
||||
Wait *waitNew(TimeMSec waitTime);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Getters/Setters
|
||||
***********************************************************************************************************************************/
|
||||
typedef struct WaitPub
|
||||
{
|
||||
TimeMSec remainTime; // Wait time remaining (in usec)
|
||||
} WaitPub;
|
||||
|
||||
// How much time is remaining? Recalculated each time waitMore() is called.
|
||||
__attribute__((always_inline)) static inline TimeMSec
|
||||
waitRemaining(const Wait *this)
|
||||
{
|
||||
ASSERT_INLINE(this != NULL);
|
||||
return ((const WaitPub *)this)->remainTime;
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Functions
|
||||
***********************************************************************************************************************************/
|
||||
// Wait and return whether the caller has more time left
|
||||
bool waitMore(Wait *this);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Getters/Setters
|
||||
***********************************************************************************************************************************/
|
||||
// How much time is remaining? Recalculated each time waitMore() is called.
|
||||
TimeMSec waitRemaining(const Wait *this);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Destructor
|
||||
***********************************************************************************************************************************/
|
||||
|
@ -306,7 +306,7 @@ testRun(void)
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
TEST_TITLE("no output from server");
|
||||
|
||||
client->timeout = 0;
|
||||
client->pub.timeout = 0;
|
||||
|
||||
hrnServerScriptAccept(http);
|
||||
|
||||
@ -469,7 +469,7 @@ testRun(void)
|
||||
httpQueryAdd(query, strNew("name"), strNew("/path/A Z.txt"));
|
||||
httpQueryAdd(query, strNew("type"), strNew("test"));
|
||||
|
||||
client->timeout = 5000;
|
||||
client->pub.timeout = 5000;
|
||||
|
||||
HttpRequest *request = NULL;
|
||||
HttpResponse *response = NULL;
|
||||
|
Loading…
Reference in New Issue
Block a user