使用 MFC 干净退出 ONC RPC SVC_RUN()

发布于 2024-11-09 14:52:37 字数 2624 浏览 2 评论 0原文

我对多线程代码非常陌生,所以我希望有人可以帮助我解决我遇到的问题。

我有一个由 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);
       }
   }
}

I'm pretty new to multi-threaded code, so I'm hoping that someone can help me with the problem I have.

I have a multi-part program comprised of an ONC/RPC server and other stuff (the "stuff" isn't really pertinent to my question, but it must be in the program with the server). Because svc_run() never returns I figured that I would put it in its own thread, and at program end I would simply terminate the thread and move on with life.

My program has now, however, expanded and I would like to cleanly, and safely, exit or close the ONC/RPC server, rather than terminate the thread. I cannot, however, figure out how to safely return from svc_run(). Can anyone help with this?

I've found a few other people with the same problem but no one seems to have responded to them. I have tried simply moving svc_run() into the same file as my server_process() function but the structures for fd_set don't get populated correctly (everything is 0), and the function fails.

svc_run() is defined in a dll created with the code found at: http://sourceforge.net/projects/oncrpc-windows/

I'm providing the pertinent elements of my code. Also note that svc_exit() does not seem to be a part of the onc/rpc system I'm currently using.

Sorry for the long question,
Thank you,

Lex

Here's my code :

 //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);
       }
   }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

心舞飞扬 2024-11-16 14:52:37

嗯,答案就在你的问题中。您必须编写自己的 svc_run() 并使用条件更改无限循环:

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

Well, the answer is in your question. You have to write your own svc_run() and change the infinite loop with conditional:

while(!done) {
  select(....)
  svc_getreqset(&readfds);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文