Skip to content
This repository has been archived by the owner on Oct 26, 2021. It is now read-only.

Commit

Permalink
Replaced sem_wait with sem_timedwait in pers_lldb_open and pers_lldb_…
Browse files Browse the repository at this point in the history
…close with 5 sec timeout
  • Loading branch information
Ingo Huerner committed Apr 6, 2017
1 parent bfbb7bd commit c1cd0d3
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 12 deletions.
1 change: 1 addition & 0 deletions inc/protected/persComErrors.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ extern "C"
#define PERS_COM_ERR_OUT_OF_MEMORY (PERS_COM_ERROR_CODE - 8) //!< Not enough resources for an opperation

#define PERS_COM_ERR_READONLY (PERS_COM_ERROR_CODE - 9) //!< Database was opened in readonly mode and cannot be written
#define PERS_COM_ERR_SEM_WAIT_TIMEOUT (PERS_COM_ERROR_CODE - 10) //!< sem_wait timeout

/* IPC specific error codes */
#define PERS_COM_IPC_ERR_PCL_NOT_AVAILABLE (PERS_COM_ERROR_CODE - 255) //!< PCL client not available (application was killed)
Expand Down
17 changes: 15 additions & 2 deletions src/key-value-store/pers_low_level_db_access.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ DLT_DECLARE_CONTEXT (persComLldbDLTCtx)

#define PERS_STATUS_KEY_NOT_IN_CACHE -10 /* /!< key not in cache */

#define SEM_TIMEDWAIT_TIMEOUT 5 // wait for seconds until sem_timedwait fails

typedef struct
{
char m_data[PERS_DB_MAX_SIZE_KEY_DATA];
Expand Down Expand Up @@ -121,6 +123,8 @@ static const char ListItemsSeparator = '\0';
static lldb_handlers_s g_sHandlers; // initialize to 0 and NULL
//static lldb_handlers_s g_sHandlers = { { { 0 } } };

static struct timespec gSemWaitTimeout;

/* ---------------------- local macros --------------------------------- */

/* ---------------------- local functions --------------------------------- */
Expand Down Expand Up @@ -284,10 +288,15 @@ sint_t pers_lldb_open(str_t const* dbPathname, pers_lldb_purpose_e ePurpose, boo
}
}
}
if (-1 == sem_wait(pLldbHandler->kissDb.kdbSem))

clock_gettime(CLOCK_REALTIME, &gSemWaitTimeout);
gSemWaitTimeout.tv_sec += SEM_TIMEDWAIT_TIMEOUT;
if(-1 == sem_timedwait(pLldbHandler->kissDb.kdbSem, &gSemWaitTimeout))
{
DLT_LOG(persComLldbDLTCtx, DLT_LOG_ERROR, DLT_STRING(__FUNCTION__); DLT_STRING(": sem_wait() in open failed: "),
DLT_STRING(strerror(errno)));

return PERS_COM_ERR_SEM_WAIT_TIMEOUT;
}
kdbState = KISSDB_open(&pLldbHandler->kissDb, path, openMode, writeMode, HASHTABLE_SLOT_COUNT, keysize, datasize);
if (kdbState != 0)
Expand Down Expand Up @@ -433,10 +442,14 @@ sint_t pers_lldb_close(sint_t handlerDB)
bLocked = true;
}

if (-1 == sem_wait(db->kdbSem))
clock_gettime(CLOCK_REALTIME, &gSemWaitTimeout);
gSemWaitTimeout.tv_sec += SEM_TIMEDWAIT_TIMEOUT;
if (-1 == sem_timedwait(db->kdbSem, &gSemWaitTimeout)) // wait for 5 seconds
{
DLT_LOG(persComLldbDLTCtx, DLT_LOG_ERROR, DLT_STRING(__FUNCTION__); DLT_STRING(": sem_wait() in close failed: "),
DLT_STRING(strerror(errno)));

return PERS_COM_ERR_SEM_WAIT_TIMEOUT;
}

DLT_LOG(persComLldbDLTCtx, DLT_LOG_DEBUG,
Expand Down
108 changes: 98 additions & 10 deletions test/test_pco_key_value_store.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include <dlt/dlt_common.h>
#include <../inc/protected/persComRct.h>
#include <../inc/protected/persComDbAccess.h>
#include <../inc/protected/persComErrors.h>
//#include <../test/pers_com_test_base.h>
//#include <../test/pers_com_check.h>
#include <check.h>
Expand Down Expand Up @@ -3315,7 +3316,86 @@ static Suite* persistenceCommonLib_suite()



void* kvdbOpenThread(void* userData)
{
int ret = -1;
int handle = -1;
const char* threadID = (const char*) userData;

sleep(1);
printf("- Started thread - read - %s\n", threadID);

printf("- do => persComDbOpen\n");
handle = persComDbOpen("/tmp/semlockTimeoutTest.db", 0x1); //create test.db if not present (cached)
printf("- do <= persComDbOpen\n");

if(handle >= 0 )
{
ret = persComDbClose(handle);
}
else if(handle == PERS_COM_ERR_SEM_WAIT_TIMEOUT)
{
printf("persComDbClose - sem_wait timedout => test PASSED\n");
}
else
{
printf("persComDbClose - common error: %d\n", handle);
}

printf("- End - thread: %d \n", handle);
pthread_exit(0);
}


void* semBlockingThread(void* userData)
{
int sleepSec = 10;
sem_t* semHandle;
const char* threadID = (const char*) userData;

printf("# Started thread - read - %s - do sem_open\n", threadID);

semHandle = sem_open("_tmp_semlockTimeoutTest_db-sem", O_CREAT | O_EXCL, 0644, 1);

printf("# Do sem_wait\n");
sem_wait(semHandle);

printf("# Now sleep %d seconds, and block persComDbOpen call from other thread\n", sleepSec);
sleep(sleepSec);

printf("# Do sem_post\n");
sem_post(semHandle);

pthread_exit(0);
}



void doSemLockTimeoutTest()
{
pthread_t threadInfoFirst, threadInfoSecond;

if(pthread_create(&threadInfoFirst, NULL, semBlockingThread, "Thread Blocking") != -1)
{
(void)pthread_setname_np(threadInfoFirst, "Blocking");
}

if(pthread_create(&threadInfoSecond, NULL, kvdbOpenThread, "Thread open") != -1)
{
(void)pthread_setname_np(threadInfoSecond, "Open");
}


if(pthread_join(threadInfoFirst, NULL) != 0) // wait
printf("pthread_join - FAILED First\n");

if(pthread_join(threadInfoSecond, NULL) != 0) // wait
printf("pthread_join - FAILED Second\n");


printf("End of lock test\n");
sem_unlink("_tmp_semlockTimeoutTest_db-sem");
}



Expand All @@ -3326,21 +3406,29 @@ int main(int argc, char* argv[])

Suite* s = persistenceCommonLib_suite();
SRunner* sr = srunner_create(s);
srunner_set_xml(sr, "/tmp/persistenceCommonObjectTest.xml");
srunner_set_log(sr, "/tmp/persistenceCommonObjectTest.log");
srunner_run_all(sr, /*CK_NORMAL*/CK_VERBOSE);

nr_failed = srunner_ntests_failed(sr);
nr_run = srunner_ntests_run(sr);
if(argc == 1)
{
srunner_set_xml(sr, "/tmp/persistenceCommonObjectTest.xml");
srunner_set_log(sr, "/tmp/persistenceCommonObjectTest.log");
srunner_run_all(sr, /*CK_NORMAL*/CK_VERBOSE);

nr_failed = srunner_ntests_failed(sr);
nr_run = srunner_ntests_run(sr);

tResult = srunner_results(sr);
for (i = 0; i < nr_run; i++)
tResult = srunner_results(sr);
for (i = 0; i < nr_run; i++)
{
(void) tr_rtype(tResult[i]); // get status of each test
}

srunner_free(sr);
}
else
{
(void) tr_rtype(tResult[i]); // get status of each test
doSemLockTimeoutTest();
}

srunner_free(sr);

dlt_free();
return (0 == nr_failed) ? EXIT_SUCCESS : EXIT_FAILURE;
}
Expand Down

0 comments on commit c1cd0d3

Please sign in to comment.