Skip to content

Instantly share code, notes, and snippets.

@halirutan
Created February 25, 2017 03:08
Show Gist options
  • Save halirutan/de3fedc11cb830cfb22b520fa680bbae to your computer and use it in GitHub Desktop.
Save halirutan/de3fedc11cb830cfb22b520fa680bbae to your computer and use it in GitHub Desktop.
Implementation of an asynchronous file watcher with Mathematica's LibraryLink
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include "WolframLibrary.h"
#ifdef _WIN32
#include <windows.h>
void PortableSleep(int timems)
{
Sleep(timems);
}
#else
#include <sys/time.h>
#include <sys/errno.h>
#include <time.h>
#include <stdlib.h>
void PortableSleep(int timems)
{
struct timespec ts;
ts.tv_sec = timems/1000;
ts.tv_nsec = (timems % 1000) * 1000000;
nanosleep(&ts, NULL);
}
#endif
typedef struct FileWatcherBackgroundArgs_st
{
WolframIOLibrary_Functions ioLibrary;
char *filename;
mint pausemillis;
}* FileWatcherBackgroundArgs;
static void FileWatcherBackgroundTask(mint asyncObjID, void* vtarg)
{
FileWatcherBackgroundArgs task_args = (FileWatcherBackgroundArgs)vtarg;
WolframIOLibrary_Functions ioLibrary = task_args->ioLibrary;
mint pausems = task_args->pausemillis;
char * filename = task_args->filename;
DataStore ds;
free(task_args);
while(ioLibrary->asynchronousTaskAliveQ(asyncObjID))
{
struct stat st = {0};
mint time;
int ret = lstat(filename, &st);
if (ret == -1){
time = -1;
} else {
time = (mint) st.st_mtim.tv_sec;
}
ds = ioLibrary->createDataStore();
ioLibrary->DataStore_addInteger(ds, time);
ioLibrary->raiseAsyncEvent(asyncObjID, "change", ds);
PortableSleep((int) pausems);
}
}
DLLEXPORT int startFileWatcher(WolframLibraryData libData, mint Argc, MArgument *Args, MArgument Res)
{
mint asyncObjID;
WolframIOLibrary_Functions ioLibrary = libData->ioLibraryFunctions;
FileWatcherBackgroundArgs threadArg = (FileWatcherBackgroundArgs)malloc(sizeof(struct FileWatcherBackgroundArgs_st));
if(Argc != 2)
return LIBRARY_FUNCTION_ERROR;
threadArg->ioLibrary = ioLibrary;
threadArg->pausemillis = MArgument_getInteger(Args[0]);
threadArg->filename = MArgument_getUTF8String(Args[1]);
asyncObjID = ioLibrary->createAsynchronousTaskWithThread(FileWatcherBackgroundTask, threadArg);
MArgument_setInteger(Res, asyncObjID);
return LIBRARY_NO_ERROR;
}
/* Return the version of Library Link */
DLLEXPORT mint WolframLibrary_getVersion( ) {
return WolframLibraryVersion;
}
/* Initialize Library */
DLLEXPORT int WolframLibrary_initialize( WolframLibraryData libData) {
return LIBRARY_NO_ERROR;
}
/* Uninitialize Library */
DLLEXPORT void WolframLibrary_uninitialize( WolframLibraryData libData) {
return;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment