EDIT3:新しいスレッドが必要になるたびに生成されます。「入力」は、内部で解放されたchar *のコピーです。 cURL関数がスレッドセーフであると仮定します。この関数はスレッドセーフですか?
EDIT4:目に見えない関数はスレッドセーフであると仮定します。
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;
}
私は、特定のシステム上の不安定な挙動を取得していると私はその疑わしいハードウェア(インテルOpenGLを?)疑いながら、私は何かを欠場かどうかを確認したいと思います。
EDIT:cURL自体がスレッドセーフであるとします。
EDIT2: "input"はこのスレッドに解放された新しいコピーです。
インテルとOpenGLとの接続は何ですか? –
これはゲームで実行されます(SDL OpenGLコンテキストで実行されます)。 OpenGLのインテルは、OpenGLのプログラマーには恐ろしい、恐ろしい、恐ろしい評判を与えているが、これでもそれを疑う余地はない。 –