Чистый выход ONC RPC SVC_RUN() с помощью MFC
Я довольно новичок в многопоточном коде, поэтому я надеюсь, что кто-то может помочь мне с моей проблемой.
У меня есть программа, состоящая из нескольких частей, состоящая из ONC/RPC-сервера и прочего ("материал" на самом деле не относится к моему вопросу, но он должен быть в программе с сервером). Поскольку svc_run() никогда не возвращается, я решил, что я поместил бы его в свой собственный поток, и в конце программы я просто завершил бы поток и продолжил жизнь.
Однако теперь моя программа расширилась, и я хотел бы чисто и безопасно выйти или закрыть сервер ONC/RPC, а не завершать поток. Однако я не могу понять, как безопасно вернуться из svc_run(). Может кто-нибудь помочь с этим?
Я нашел несколько других людей с такой же проблемой, но никто, похоже, не ответил на них. Я попытался просто переместить svc_run() в тот же файл, что и моя функция server_process(), но структуры для fd_set не заполняются правильно (все равно 0), и функция завершается ошибкой.
svc_run() определяется в DLL, созданной с помощью кода, найденного по адресу: http://sourceforge.net/projects/oncrpc-windows/
Я предоставляю соответствующие элементы моего кода. Также обратите внимание, что svc_exit() не является частью системы onc/rpc, которую я сейчас использую.
Извините за длинный вопрос, спасибо,
закон
Вот мой код:
//Code in Initialization of MFC Dialog
myThread = AfxBeginThread(startServing,NULL,THREAD_PRIORITY_NORMAL,0,0,NULL);
// Thread that starts the server
UINT __cdecl startServing(LPVOID pParam)
{
if(server_process())
AfxMessageBox(_T("Error Starting the VXI 11 Server."));
AfxEndThread(0,TRUE); //I never get here.
return 0;
}
//How I would like to stop the thread:
void myDlg::OnBnClickedQuit()
{
DWORD threadStatus;
endThread = 1; //static or extern that could be monitored if svc_run()
//wasn't in a dll
threadStatus = WaitForSingleObject(myThread->m_hThread, INFINITE);
OnOk(); //for the ok modal to close the progam
}
//How I end up stopping my thread
void myDlg::OnBnClickedQuit()
{
TerminateThread(myThread->m_hThread,1);
OnOk(); //for the ok modal to close the progam
}
int server_process()
{
//Portmap and server registration code
.
.
.
.
svc_run(); //ideally I'd be able to monitor a global in here
(void)fprintf(stderr, "svc_run returned\n");
#ifdef WIN32
rpc_nt_exit();
#endif
return(1);
}// end of server Process
// Function in the dll I'm calling
void svc_run()
{
#ifdef FD_SETSIZE
fd_set readfds;
#else
int readfds;
#endif /* def FD_SETSIZE */
#ifndef WIN32
extern int errno;
#endif
for (;;) {
#ifdef FD_SETSIZE
readfds = svc_fdset;
#else
readfds = svc_fds;
#endif /* def FD_SETSIZE */
#ifdef WIN32
switch (select(0 /* unused in winsock */, &readfds, NULL, NULL,
#else
switch (select(_rpc_dtablesize(), &readfds, (int *)0, (int *)0,
#endif
(struct timeval *)0)) {
case -1:
#ifdef WIN32
if (WSAerrno == EINTR) {
#else
if (errno == EINTR) {
#endif
continue;
}
perror("svc_run: - select failed");
return;
case 0:
continue;
default:
svc_getreqset(&readfds);
}
}
}
1 ответ
Ну, ответ на ваш вопрос. Вы должны написать свой собственный svc_run()
и изменить бесконечный цикл с условным:
while(!done) {
select(....)
svc_getreqset(&readfds);
}