| 1017 | } |
| 1018 | |
| 1019 | void ProfilerListener::watcherThread() |
| 1020 | { |
| 1021 | bool startup = true; |
| 1022 | auto& sharedMemory = ipc->sharedMemory; |
| 1023 | const auto header = sharedMemory->getHeader(); |
| 1024 | |
| 1025 | fb_assert(header->tag == ProfilerIpc::Tag::NOP); |
| 1026 | header->tag = ProfilerIpc::Tag::SERVER_STARTED; |
| 1027 | |
| 1028 | try |
| 1029 | { |
| 1030 | while (!exiting) |
| 1031 | { |
| 1032 | const SLONG value = sharedMemory->eventClear(&header->serverEvent); |
| 1033 | |
| 1034 | if (startup) |
| 1035 | { |
| 1036 | startup = false; |
| 1037 | startupSemaphore.release(); |
| 1038 | } |
| 1039 | else |
| 1040 | { |
| 1041 | fb_assert(header->tag >= ProfilerIpc::Tag::FIRST_CLIENT_OP); |
| 1042 | |
| 1043 | try |
| 1044 | { |
| 1045 | FbLocalStatus statusVector; |
| 1046 | EngineContextHolder tdbb(&statusVector, attachment->getInterface(), FB_FUNCTION); |
| 1047 | |
| 1048 | processCommand(tdbb); |
| 1049 | header->tag = ProfilerIpc::Tag::RESPONSE; |
| 1050 | } |
| 1051 | catch (const status_exception& e) |
| 1052 | { |
| 1053 | //// TODO: Serialize status vector instead of formated message. |
| 1054 | |
| 1055 | const ISC_STATUS* status = e.value(); |
| 1056 | string errorMsg; |
| 1057 | TEXT temp[BUFFER_LARGE]; |
| 1058 | |
| 1059 | while (fb_interpret(temp, sizeof(temp), &status)) |
| 1060 | { |
| 1061 | if (errorMsg.hasData()) |
| 1062 | errorMsg += "\n\t"; |
| 1063 | |
| 1064 | errorMsg += temp; |
| 1065 | } |
| 1066 | |
| 1067 | header->bufferSize = MIN(errorMsg.length(), sizeof(header->buffer) - 1); |
| 1068 | strncpy((char*) header->buffer, errorMsg.c_str(), sizeof(header->buffer)); |
| 1069 | header->buffer[header->bufferSize] = '\0'; |
| 1070 | |
| 1071 | header->tag = ProfilerIpc::Tag::EXCEPTION; |
| 1072 | } |
| 1073 | |
| 1074 | sharedMemory->eventPost(&header->clientEvent); |
| 1075 | } |
| 1076 |
no test coverage detected