1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
/*
 * optim_wizard_5.c
 *
 *  Created on: Mar 24, 2011
 *      Author: ngitcho
 */

/* My code makes parallel calls to 3 location site (written in php) to get a value from
 * each of them (what is called cpc in the code),processes those values and returns the 
 * max of those cpc
 */

#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <time.h>
#include <curl/curl.h>
#include <curl/types.h>
#include <curl/easy.h>
#include <string.h>
#define NTHREADS 3

typedef struct myStruct myStruct;
struct myStruct{char *url;
		float cpc;};

/* Function prototypes to define later */
void *getCpc(void *ptr);
float getCpc_max(float *arg);
char *do_web_request(char *url);
size_t write_data(void *buffer, size_t size, size_t nmemb, void *userp);
float request_cpc();

char *table[NTHREADS] = {"http://localhost/Index/index1.php","http://localhost/Index/index2.php","http://localhost/Index/index3.php"};

int main(int *argc, char **argv){

	printf("the cpc max is %.2f\n",request_cpc());
	exit(0);
}

float request_cpc(){
	pthread_t *thread;
	myStruct *tmp;
	float *cpc;
	int i,j;

	thread = malloc(NTHREADS * sizeof(pthread_t));
	tmp = malloc(NTHREADS * sizeof(myStruct));
	cpc = malloc(NTHREADS * sizeof(float));

	// Initialize cpc array
	for(i = 0;i < NTHREADS;i++){
		tmp[i].cpc = 0.0;
		tmp[i].url = table[i];
	}

	//for(i = 0;i < NTHREADS;i++)
		//printf("%s\n",tmp[i].url);

	// Create differents threads each of which will execute the function getCpc()
	for(i = 0;i < NTHREADS;i++)
		pthread_create(&thread[i],NULL,getCpc,&tmp[i]);

	/* Wait until threads are complete before main executes.Unless we
	 * wait we run the risk to run an exit which will terminate the
	 * processs and all threads before the threads have completed
	 */
	for(j = 0;j < NTHREADS;j++)
		pthread_join(thread[j],NULL);

	printf("CPCs among all DSPs are : \n");
	for(i = 0;i < NTHREADS;i++){
		cpc[i] = tmp[i].cpc;
		printf("%.2f\t",tmp[i].cpc);
	}
	printf("\n");

	// Print the maximum cpc among all the cpc values
	//printf("the max cpc is %.2f\n",getCpc_max(cpc));

	free(cpc);
	free(tmp);
	free(thread);

	return getCpc_max(cpc);
}

/* Call to differents DSPs and get the cpc back.
 * DSPs are written in PHP
 */
void *getCpc(void *ptr){
	char *content = NULL;
	myStruct *tmp;
	tmp = (myStruct *)ptr;

	content = do_web_request(tmp->url);
	tmp->cpc = atof(content);
	//printf("Thread %ld has a cpc equals to %.2f\n",pthread_self(),tmp->cpc);
}

/* Compute and return the CPC max over all CPC values */
float getCpc_max(float *arg){
	float tmp = arg[0];
	int i = 0;

	for(i = 1;i < NTHREADS;i++){
		if(arg[i-1] < arg[i]){
			tmp = arg[i];
		}
	}

	return tmp;
}

/* The function that returns the content for a given URL */
char *do_web_request(char *url){
	/* Keep the handle to the curl object */
	CURL *curl_handle = NULL;
	/* to the response */
	char * response = NULL;

	double timeout = 1.0;


	/* Initializing curl and setting the url */
	curl_handle = curl_easy_init();
	curl_easy_setopt(curl_handle,CURLOPT_URL,url);
	curl_easy_setopt(curl_handle,CURLOPT_HTTPGET,1);

	/* Set the timeout in ms */
	curl_easy_setopt(curl_handle,CURLOPT_TIMEOUT_MS,timeout);

	/* Follow locations specified by the response header */
	curl_easy_setopt(curl_handle,CURLOPT_FOLLOWLOCATION,1);

	/* Setting a call back function to return the data */
	curl_easy_setopt(curl_handle,CURLOPT_WRITEFUNCTION,write_data);

	/* Passing the pointer to the response as the callback parameter */
	curl_easy_setopt(curl_handle,CURLOPT_WRITEDATA,&response);

	/* Perform the request */
	curl_easy_perform(curl_handle);

	/* Cleaning up all curl stuff */
	curl_easy_cleanup(curl_handle);

	return response;

}

/* The function to invoke as the data received */
size_t write_data(void *buffer, size_t size, size_t nmemb, void *userp){
	char **response_ptr = (char **)userp;

	/* Assuming the response is a string */
	*response_ptr = strndup(buffer,(size_t)(size * nmemb));
}