Skip to content

Instantly share code, notes, and snippets.

@sakishum
Forked from icebreaker/jobs.cpp
Created June 3, 2013 02:44
Show Gist options
  • Save sakishum/5695857 to your computer and use it in GitHub Desktop.
Save sakishum/5695857 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <curl/curl.h>
#define MAX_JOBS 10
//
// Released into the public domain.
//
// WARNING: this is not production quality code! Consider yourself warned.
//
// compile and run via: g++ jobs.cpp -o jobs -lpthread -lcurl; ./jobs
//
class Job
{
friend class JobManager;
public:
Job(void) : mHandle(NULL), mFinished(false) {}
virtual ~Job(void) { join(); }
virtual void process(void) = 0;
virtual void start(void) { pthread_create( &mHandle, NULL, proxy, this); }
virtual void join(void) { if(mHandle) { pthread_join(mHandle, NULL); mHandle = NULL; } }
public:
static void *proxy(void *pJob) { reinterpret_cast<Job *>(pJob)->process(); }
protected:
bool mFinished;
private:
pthread_t mHandle;
};
class JobManager
{
public:
JobManager(void) : mNumJobs(0)
{
for(int i=0; i<MAX_JOBS; i++)
mJobs[i] = NULL;
}
virtual ~JobManager(void)
{
for(int i=0; i<MAX_JOBS; i++)
{
if(mJobs[i] != NULL)
delete mJobs[i];
}
}
void addJob(Job *pJob)
{
if(mNumJobs == MAX_JOBS)
return;
mJobs[mNumJobs++] = pJob;
pJob->start();
}
bool process(void)
{
for(int i=0; i<MAX_JOBS; i++)
{
if(mJobs[i] != NULL && mJobs[i]->mFinished)
{
finished(mJobs[i]);
delete mJobs[i];
mJobs[i] = NULL;
--mNumJobs;
}
}
return (mNumJobs > 0);
}
virtual void finished(Job *pJob) = 0;
private:
Job *mJobs[MAX_JOBS];
int mNumJobs;
};
class MyJob : public Job
{
friend class MyJobManager;
public:
MyJob(const char *pUsername) : mUsername(pUsername) {}
virtual void process(void)
{
mValue = (rand() % 5) + 1;
sleep(mValue);
CURL *curl;
CURLcode res;
curl = curl_easy_init();
if(curl)
{
char tmp[128] = {0,};
snprintf(tmp, 128, "%s%s", "https://api.github.com/users/", mUsername);
curl_easy_setopt(curl, CURLOPT_URL, tmp);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_proxy);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, this);
curl_easy_perform(curl);
curl_easy_cleanup(curl);
}
mFinished = true;
}
void process_data(char *pData, size_t pSize)
{
printf("%s\n", pData);
fflush(stdout);
}
static int write_proxy(char *pData, size_t pSize, size_t pNum, void *pJob)
{
reinterpret_cast<MyJob *>(pJob)->process_data(pData, pSize);
return pSize * pNum;
}
private:
const char *mUsername;
int mValue;
};
class MyJobManager : public JobManager
{
public:
virtual ~MyJobManager() {}
virtual void finished(Job *pJob)
{
MyJob *job = static_cast<MyJob *>(pJob);
printf("%s = %d\n", job->mUsername, job->mValue);
fflush(stdout);
}
};
int main(int argc, char *argv[])
{
srand(time(NULL));
MyJobManager jobs;
jobs.addJob(new MyJob("hello"));
jobs.addJob(new MyJob("world"));
jobs.addJob(new MyJob("drunk"));
jobs.addJob(new MyJob("dingo"));
while(jobs.process())
{
printf("waiting ...\n");
sleep(1);
}
printf("done!\n");
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment