Skip to content

Commit

Permalink
wip: stopme, condwait, test
Browse files Browse the repository at this point in the history
  • Loading branch information
SimonKagstrom committed Jul 9, 2017
1 parent 42cf66b commit c237ce0
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 7 deletions.
73 changes: 66 additions & 7 deletions src/main-system-daemon.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <fcntl.h>
#include <sched.h>
#include <pthread.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
Expand Down Expand Up @@ -91,8 +92,6 @@ class ProcessHandler : public IEngine::IEventListener
panic("Output not created in run(), check implementation\n");
}



while (1)
{
bool rv = continueExecution();
Expand Down Expand Up @@ -225,11 +224,31 @@ static void processOne(const std::string &destinationDir, const std::string &fil
delete sysFile;
}


// https://stackoverflow.com/questions/1486833/pthread-cond-timedwait-help
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
static void waitCond(unsigned secs)
{
struct timespec timeToWait;
struct timeval now;

gettimeofday(&now,NULL);

timeToWait.tv_sec = now.tv_sec + secs;
timeToWait.tv_nsec = now.tv_usec;

pthread_mutex_lock(&mutex);
pthread_cond_timedwait(&cond, &mutex, &timeToWait);
pthread_mutex_unlock(&mutex);
}

static bool doExit = false;
static void onExitSignal(int sig)
{
// Forward the signal to the traced program
doExit = true;
pthread_cond_signal(&cond);
}

static void *outputThread(void *p)
Expand All @@ -241,14 +260,14 @@ static void *outputThread(void *p)

while (1)
{
// Write data every two seconds
waitCond(2);

if (doExit)
{
break;
}

// Write data every two seconds
sleep(2);

// Copy to a list to process
std::vector<std::pair<uint32_t, kcov_system_mode::system_mode_memory *>> toProcess;
outputFileMutex.lock();
Expand Down Expand Up @@ -304,6 +323,7 @@ static void *outputThread(void *p)
return NULL;
}

// https://stackoverflow.com/questions/17954432/creating-a-daemon-in-linux/17955149#17955149
static void daemonize(void)
{
pid_t child;
Expand All @@ -316,13 +336,18 @@ static void daemonize(void)
}
else if (child > 0)
{
// Parent
exit(0);
}
if (setsid() < 0)
{
exit(1);
}

// Ignore signals
signal(SIGCHLD, SIG_IGN);
signal(SIGHUP, SIG_IGN);

child = fork();

if (child < 0)
Expand All @@ -331,21 +356,38 @@ static void daemonize(void)
}
else if (child > 0)
{
// Parent
exit(0);
}

close(fileno(stdin));
close(fileno(stderr));
close(fileno(stdout));
}


int main(int argc, const char *argv[])
{
char buf[4096];
const char *path = getenv("KCOV_SYSTEM_DESTINATION_DIR");
std::string pidFile = "/tmp/kcov-system.pid";

if (file_exists(pidFile))
{
fprintf(stderr, "%s already exists, indicating an already running daemon\n"
"Remove the file if this is incorrect\n", pidFile.c_str());
exit(1);
}

const char *path = getenv("KCOV_SYSTEM_DESTINATION_DIR");
if (argc == 2 && strcmp(argv[1], "-d") == 0)
{
daemonize();
}

// Create PID-file
char pid[256];
snprintf(pid, sizeof(pid), "%d", getpid());
write_file(pid, strlen(pid) + 1, "%s", pidFile.c_str());

std::string destinationDir = "/tmp/kcov-data";

if (path)
Expand All @@ -360,6 +402,7 @@ int main(int argc, const char *argv[])
if (fd < 0)
{
fprintf(stderr, "Can't open fifo %s\n", pipePath);
unlink(pidFile.c_str());
exit(1);
}

Expand All @@ -372,6 +415,8 @@ int main(int argc, const char *argv[])

while (1)
{
char buf[4096];

if (doExit)
{
break;
Expand All @@ -384,6 +429,15 @@ int main(int argc, const char *argv[])
continue;
}

// Handle stopping requests
std::string stopCommand = "STOPME";
if (r >= (int)stopCommand.size() &&
strncmp(stopCommand.c_str(), buf, stopCommand.size()) == 0)
{
doExit = 1;
break;
}

if (r < (int)sizeof(struct new_process_entry))
{
continue;
Expand All @@ -404,8 +458,13 @@ int main(int argc, const char *argv[])
// Write a character to let the process loose again
write_file(buf, 1, "%s/%d", destinationDir.c_str(), pid);
}
pthread_cond_signal(&cond);

// Wait for the reporter thread
void *rv;
pthread_join(thread, &rv);

close(fd);
unlink(pipePath);
unlink(pidFile.c_str());
}
1 change: 1 addition & 0 deletions tests/tools/run-tests
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ from basic import *
from compiled import *
if sys.platform.startswith("linux"):
from bash_linux_only import *
from system_mode import *
from filter import *
from accumulate import *
from python import *
Expand Down
25 changes: 25 additions & 0 deletions tests/tools/system_mode.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import testbase
import os
import time
import unittest
import parse_cobertura

class SystemModeBase(testbase.KcovTestCase):
def writeToPipe(self, str):
f = open("/tmp/kcov-system.pipe", "w")
f.write(str)
f.close()

class system_mode_can_start_and_stop_daemon(SystemModeBase):
def runTest(self):
self.setUp()
rv,o = self.do(testbase.kcov_system_daemon + " -d", False)

pf = "/tmp/kcov-system.pid"
assert os.path.isfile(pf)

self.writeToPipe("STOPME")

time.sleep(2)

assert os.path.isfile(pf) == False

0 comments on commit c237ce0

Please sign in to comment.