
#include <curl/curl.h>
#include <stdlib.h>

#ifdef WIN32
#include <time.h>
#include <windows.h>
#else
#include <pthread.h>
#endif

#define TRUE 1
#define FALSE 0
#define NUM_THREADS 8
#define URL "http://127.0.0.1/1M.bin"

unsigned long bytes_read;

size_t
update_read(void *ptr, size_t size, size_t nmemb, void *stream)
{
	bytes_read += size * nmemb;
	return size * nmemb;
}

#ifdef WIN32
DWORD WINAPI
worker_main(LPVOID lpParam)
#else
void *
worker_main(void *nothing)
#endif
{
	int i, rv;
	CURL *curl;

	if ((curl = curl_easy_init()) == NULL)
		exit(1);

	if ((rv = curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, update_read)) != 0)
		exit(1);

	if ((rv = curl_easy_setopt(curl, CURLOPT_FAILONERROR, TRUE)) != 0)
		exit(1);

	if ((rv = curl_easy_setopt(curl, CURLOPT_URL, URL)) != 0)
		exit(1);

	for (i = 0; i < 64; ++i)
	{
		if ((rv = curl_easy_perform(curl)) != 0)
			exit(1);

	}

	curl_easy_cleanup(curl);

#ifdef WIN32
	return 0;
#else
	return NULL;
#endif
}

int
main(int argc, char *argv[])
{
	int i;
#ifdef WIN32
	DWORD wait;
	HANDLE worker_handles[NUM_THREADS];
	DWORD worker_tids[NUM_THREADS];
#else
	pthread_t worker_tids[NUM_THREADS];
#endif
	time_t start = time(NULL);
	time_t elapsed;

	bytes_read = 0;

	for (i = 0; i < NUM_THREADS; ++i)
	{
#ifdef WIN32
		if ((worker_handles[i] = CreateThread(NULL, 0, worker_main, NULL, 0, &worker_tids[i])) == NULL)
			exit(1);
#else

		if (pthread_create(&worker_tids[i], NULL, worker_main, NULL) != 0)
			exit(1);
#endif
	}

	/* wait for threads to terminate */
#ifdef WIN32
	wait = WaitForMultipleObjects(NUM_THREADS, worker_handles, TRUE, INFINITE);
#else
	for(i = 0; i < NUM_THREADS; ++i)
		pthread_join(worker_tids[i], NULL);
#endif

	elapsed = time(NULL) - start;
	printf("Retrieved %luB in %ld seconds at a rate of %luB/s\n", bytes_read, elapsed, bytes_read / elapsed);

	return 0;
}

