Чистый выход из ONC RPC SVC_RUN() с помощью MFC

#multithreading #rpc #sunrpc

#многопоточность #rpc #sunrpc

Вопрос:

Я довольно новичок в многопоточном коде, поэтому я надеюсь, что кто-нибудь сможет помочь мне с моей проблемой.

У меня есть программа, состоящая из нескольких частей, состоящая из 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 returnedn");
#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 */, amp;readfds, NULL, NULL,
#else
    switch (select(_rpc_dtablesize(), amp;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(amp;readfds);
       }
   }
}
  

Ответ №1:

Что ж, ответ содержится в вашем вопросе. Вы должны написать свой собственный svc_run() и изменить бесконечный цикл на условный:

 while(!done) {
  select(....)
  svc_getreqset(amp;readfds);
}