so i try to make a fast translator that can do max 3 requests at the same time. i have 3 functions like this (mainThead0) but:
- with different names (mainThead0, mainThead1, mainThead2)
- and the bool at the end (mT0, mT1, mT2) //this is about to check if the thread is already busy with previous requst or if can use it.
PRrunning and PTrunning are just 2 bool outside of any function.
struct translateInfo
{
string translatedText;
string originalText;
string language_detected;
bool ip_blocked;
int error;
int providerUsed;
};
struct translateData
{
bool ready;
int id; //index in queue //-1 = invalid
translateInfo output;
string InputText;
int service;
int targetLang;
int sourceLang;
};
DWORD WINAPI mainThead0(LPVOID lpStatus) {//passing args with a struct
translateData* info = reinterpret_cast<translateData*>(lpStatus);
while (PRrunning) { PRrunning ? Sleep(0) : PRrunning = true; } //if other thread using prepare_request function, when wait until finish
string data = prepare_request //prepare request
(
info->InputText.c_str(),
(TranslateServiceProvider)info->service,
(supportedLang)info->targetLang,
(supportedLang)info->sourceLang
);
PRrunning = false;
//AND HERE MAYBE IS THE PROBLEM!! i think if i call the Get function multiple times at the same time it cause problems and sometimes crash!
net::requests m_request(L"f", false); //here i send the requst and wait for server answer
std::wstring answer = m_request.Get(false, (wchar_t*)c2wc(data.c_str())); //send rerquest and get data
data = ws2s(answer);
if (answer.empty()) {
info->output.error = request_failed_to_return_data;
}
else if (data.empty()) {
info->output.error = failed_to_get_translate_data;
}
else {
string answer;
for (int x = 0; x < data.length(); x++)
{ answer += data.at(x) == data.at(data.find("<!DOCTYPE html") == string::npos ? 1 : 77) ? '?' : data.at(x); } //just repace all " to ? to avoid some problems
answer += to_string(info->service);
while (PTrunning) { PTrunning ? Sleep(0) : PTrunning = true; }
translateInfo mTi;
mTi = process_translate //split/check raw data and add info to queue
(
answer,
info->InputText.c_str()
);
PTrunning = false;
info->output = mTi;
}
mT0 = false;
return 0;
}
then i have this to check which thread can use
int checkTheeadsPriority() { //priority/free thread check
if (!mT0)
return 0;
if (!mT1)
return 1;
if (!mT2)
return 2;
return -1;
}
and finally the main function: there is a vector named TransQueue. by calling the addToQueue it add the given struct in the TransQueue and return the index (where located in vector).
int translate_text(const char* text, TranslateServiceProvider serviceProvider, supportedLang targetLang, supportedLang sourceLang) {
translateData t_info = { false, -1, {}, string(text), serviceProvider, targetLang, sourceLang };
int handle = addToQueue(t_info);
TransQueue.at(handle).id = handle;
if (strlen(text) <= 1) {
//some error msg here
TransQueue.at(handle).output.error = given_text_is_less_than_2_letters; //this is enum
return handle;
}
LABEL_1:
if (checkTheeadsPriority() != -1) {
switch (checkTheeadsPriority()) {
case 0:
{
mT0 = true;
CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)mainThead0, &TransQueue.at(handle), NULL, NULL);
}
break;
case 1:
{
mT1 = true;
CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)mainThead1, &TransQueue.at(handle), NULL, NULL);
}
break;
case 2:
{
mT2 = true;
CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)mainThead2, &TransQueue.at(handle), NULL, NULL);
}
}
}
else {
//at this point all threads are busy so will do a actually loop until a thread finish
goto LABEL_1;
}
return handle;
}
now the problem is when i call like 10 times fast (i did also with 2 and works good, but sometimes may crash too) the translate_text it crash (for some reason it crash usually at the end of the mainThead0, maybe after do the return 0;) idk why there but i think it happend because 2 threads call the m_request.Get() at the same time. the net::requests m_request
in mainThead0 is diff than this in mainThead1 (its other function so its local var). but i think if call the Get at the same time it pass the args from thread0 normally and then before finish, it pass new args from thread1 for example!? im not sure about that. the Get function is from a ready header so idk how it works. Any possible fix? this is my first time i work with async coding, so idk if i made something wrong.
Aucun commentaire:
Enregistrer un commentaire