EDIT3: Il apparaît dans un nouveau thread chaque fois qu'il est nécessaire, "input" est une copie d'un char * qui est libéré à l'intérieur. Supposons que les fonctions cURL sont thread safe.Cette fonction est-elle parfaitement sûre pour les threads?
EDIT4: Supposons que toutes les fonctions non visibles sont sécurisées par les threads.
static void *Com_GoogleTranslate(void* input) {
CURL *easy_handle;
char *pos1, *pos2, url[1024], final[1024], inlang[8], outlang[8], *encoded;
const int const_strlen = strlen("\"translatedText\":\"");
struct GoogleMem chunk;
pthread_mutex_lock(&GoogleMessage_mutex);
// 'auto' is really empty in google API:
if (!strcmp(clu.translateIn->string, "auto"))
strcpy(inlang, "");
else
strcpy(inlang, clu.translateIn->string);
if (!strcmp(clu.translateOut->string, "auto"))
strcpy(outlang, "");
else
strcpy(outlang, clu.translateOut->string);
pthread_mutex_unlock(&GoogleMessage_mutex);
// Build the URL
url[0] = '\0';
strcat(url, "http://ajax.googleapis.com/ajax/services/language/translate?v=1.0&q=");
// Encode input into URL formatting
encoded = url_encode((char*)input);
if (!encoded) return 0;
strcat(url, encoded);
strcat(url, "&langpair=");
strcat(url, inlang);
strcat(url, "|");
strcat(url, outlang);
chunk.memory = malloc(1); // realloc grows it at Com_GoogleTranslateMem()
if (!chunk.memory) return 0;
chunk.size = 0; // no data yet
// cURL initialization for this sub-session:
easy_handle = qcurl_easy_init();
// ioq3-urt: was needed on https:// (v2 API) attempts when using GnuTLS
//qcurl_easy_setopt(curl_handle, CURLOPT_SSLVERSION, 3);
// set URL:
qcurl_easy_setopt(easy_handle, CURLOPT_URL, url);
// ioq3-urt: required for multithreading according to cURL doc.
qcurl_easy_setopt(easy_handle, CURLOPT_NOSIGNAL, 1);
// ioq3-urt: skip peer verification; required for google translate when SSL was used
//qcurl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 0L);
// send all data to this function
qcurl_easy_setopt(easy_handle, CURLOPT_WRITEFUNCTION, Com_GoogleTranslateMem);
// we pass our 'chunk' struct to the callback function:
qcurl_easy_setopt(easy_handle, CURLOPT_WRITEDATA, (void *)&chunk);
// some servers don't like requests that are made without a user-agent field, so we provide one:
qcurl_easy_setopt(easy_handle, CURLOPT_USERAGENT, "libcurl-agent/1.0");
// ioq3-urt: Required by Google Translate terms:
qcurl_easy_setopt(easy_handle, CURLOPT_REFERER, "ioq3-urt");
// fetch it
qcurl_easy_perform(easy_handle);
// cleanup curl stuff
qcurl_easy_cleanup(easy_handle);
/*
Now chunk.memory points to a memory block that is chunk.size
bytes big and contains the remote file.
Nothing has yet deallocated that data, hence free() is used at the end.
*/
if (!chunk.size) {
pthread_mutex_lock(&GoogleMessage_mutex);
sprintf(GoogleMessage.message, "Translation: no data received from Google\n");
GoogleMessage.new_message = qtrue;
pthread_mutex_unlock(&GoogleMessage_mutex);
// Free up memory (same with the end)
if(chunk.memory) free(chunk.memory);
free(encoded);
free(input);
return 0;
}
if ((pos1 = strstr(chunk.memory, "\"translatedText\":\""))) { // Make sure we use a valid file:
pos2 = strstr(pos1 + const_strlen, "\""); // position translated text ends
// Build the translated text:
final[0] = '\0';
strncat(final, pos1 + const_strlen, strlen(pos1) - (strlen(pos2) + const_strlen));
// Final printing of the translated text:
pthread_mutex_lock(&GoogleMessage_mutex);
sprintf(GoogleMessage.message, "^2Translated^7: ^3%s\n", final);
GoogleMessage.new_message = qtrue;
pthread_mutex_unlock(&GoogleMessage_mutex);
#ifdef BUILD_FREETYPE
TTF_Find_Slot(final, clu.TTF_MessageMaxTime->integer);
#endif
} else {
pthread_mutex_lock(&GoogleMessage_mutex);
sprintf(GoogleMessage.message, "Translation: no valid translation file received from Google\n");
GoogleMessage.new_message = qtrue;
pthread_mutex_unlock(&GoogleMessage_mutex);
}
// Free allocated memory
if(chunk.memory) free(chunk.memory);
free(encoded);
free(input);
return 0;
}
Je reçois un comportement instable sur certains système seulement et alors que je soupçonne que son matériel douteux (Intel OpenGL?), Je voudrais savoir si je manque quelque chose.
EDIT: Supposons que cURL est thread-safe en lui-même.
EDIT2: "entrée" est une nouvelle copie qui est libérée dans ce fil de discussion.
Quelle est la connexion à Intel et OpenGL? –
Il fonctionne dans un jeu (qui s'exécute dans un contexte SDL OpenGL). La fonction n'appelle pas directement ou indirectement aucune fonction OpenGL (qui est intrinsèquement dangereuse n'importe où), cependant, Intel dans OpenGL a une réputation horrible, horrible, horrible pour les programmeurs OpenGL que je ne peux m'empêcher de suspecter même dans ce cas. –