-
-
Save sakishum/5695857 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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