Argonne National Laboratory

Experimental Physics and
Industrial Control System

1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  <20052006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  Index 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  <20052006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020 
<== Date ==> <== Thread ==>

Subject: RE: Channel access problem on cygwin IOC
From: "Jeff Hill" <johill@lanl.gov>
To: "'Mark Rivers'" <rivers@cars.uchicago.edu>, <tech-talk@aps.anl.gov>
Date: Fri, 30 Sep 2005 16:14:12 -0600
Mark,

> The copy of caRepeater that was started under
> cygwin had the unfortunate property that it had a file open that my IOC
> application had opened, and that file could not be deleted until that copy
> of caRepeater was killed.

This is a fun "feature" of POSIX. On POSIX subsystems we used to close *all*
file numbers (other than stdin/out/err) before launching the caRepeater
using exec in the process created with fork. We received a complaint that
this was too intrusive (I think that there was some issue on HPUX).
Therefore, base now open all sockets specifying the FD_CLOEXEC option and
lets the OS take care of this matter. 

You will also need to set the FD_CLOEXEC option when opening a file on POSIX
systems in any process that uses fork and exec to start a detached process.

Attached are the codes that start the caRepeater depending on if the
repeater is started with cygwin-x86 (POSIX) or with win32-x86.

> I then started medm on the Windows machine, which created a caRepeater
> task that shows up in the Windows Task Manager.  That time starting the
> IOC did not start a caRepeater task, since it must have found the one that
> was running under Windows.  However, I still got the following error at
> the IOC:
> ***
> epics> CA client library is unable to contact CA repeater a
>
> Do you understand what is going on?

Nope. My guess is that the cygwin socket subsystem somehow isn't forwarding
UDP to the win32 socket subsystem.

And I was whining about having to support both cygwin-x86 and win32-x86 when
I dint know that we could look forward to the "cygwin-x86-blend-win32-x86"
system :-)

Jeff

On POSIX:

epicsShareFunc osiSpawnDetachedProcessReturn epicsShareAPI
osiSpawnDetachedProcess 
    (const char *pProcessName, const char *pBaseExecutableName)
{
    int status;
    
    /*
     * create a duplicate process
     */
    status = fork ();
    if (status < 0) {
        return osiSpawnDetachedProcessFail;
    }

    /*
     * return to the caller
     * if its in the initiating process
     */
    if (status) {
        return osiSpawnDetachedProcessSuccess;
    }

    /*
     * since all epics sockets are created with the FD_CLOEXEC
     * option then we no-longer need to blindly close all open
     * files here.
     */

    /*
     * overlay the specified executable
     */
    status = execlp (pBaseExecutableName, pBaseExecutableName, NULL);
    if ( status < 0 ) { 
        fprintf ( stderr, "**** The executable \"%s\" couldn't be
located\n", pBaseExecutableName );
        fprintf ( stderr, "**** because of errno = \"%s\".\n", strerror
(errno) );
        fprintf ( stderr, "**** You may need to modify your PATH environment
variable.\n" );
        fprintf ( stderr, "**** Unable to start \"%s\" process.\n",
pProcessName);
    }
    exit ( -1 );
}

On WIN32:

epicsShareFunc osiSpawnDetachedProcessReturn epicsShareAPI
osiSpawnDetachedProcess 
    ( const char *pProcessName, const char *pBaseExecutableName )
{
	BOOL status;
	STARTUPINFO startupInfo;
	PROCESS_INFORMATION processInfo;

	GetStartupInfo ( &startupInfo ); 
	startupInfo.lpReserved = NULL;
	startupInfo.lpTitle = (char *) pProcessName;
	startupInfo.dwFlags = STARTF_USESHOWWINDOW;
	startupInfo.wShowWindow = SW_SHOWMINNOACTIVE;
	
	status =  CreateProcess ( 
		            NULL, // pointer to name of executable module
(not required if command line is specified)
		            (char *) pBaseExecutableName, // pointer to
command line string 
		            NULL, // pointer to process security attributes 
		            NULL, // pointer to thread security attributes 
		            FALSE, // handle inheritance flag 
		            CREATE_NEW_PROCESS_GROUP | DETACHED_PROCESS, //
creation flags 
		            NULL, // pointer to new environment block
(defaults to caller's environement)
		            NULL, // pointer to current directory name
(defaults to caller's current directory)
		            &startupInfo, // pointer to STARTUPINFO 
		            &processInfo // pointer to PROCESS_INFORMATION 
	); 
	if ( status == 0 ) {
		DWORD W32status;
		LPVOID errStrMsgBuf;
		LPVOID complteMsgBuf;

		W32status = FormatMessage ( 
			FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM,
			NULL,
			GetLastError (),
			MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), //
Default language
				(LPTSTR) &errStrMsgBuf,
			0,
			NULL 
		);

		if ( W32status ) {
			char *pFmtArgs[6];
            pFmtArgs[0] = "Failed to start executable -";
            pFmtArgs[1] = (char *) pBaseExecutableName;
            pFmtArgs[2] = errStrMsgBuf;
            pFmtArgs[3] = "Changes may be required in your \"path\"
environment variable.";
            pFmtArgs[4] = "PATH = ";
            pFmtArgs[5] = getenv ("path");
			if ( pFmtArgs[5] == NULL ) {
				pFmtArgs[5] = "<empty string>";
			}

			W32status = FormatMessage( 
				FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_STRING | 
					FORMAT_MESSAGE_ARGUMENT_ARRAY | 80,
				"%1 \"%2\". %3 %4 %5 \"%6\"",
				0,
				MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
// Default language
				(LPTSTR) &complteMsgBuf,
				0,
				pFmtArgs 
			);
			if (W32status) {
				// Display the string.
				MessageBox (NULL, complteMsgBuf,
"Configuration Problem", 
					MB_OK | MB_ICONINFORMATION);
				LocalFree (complteMsgBuf);
			}
			else {
				// Display the string.
				MessageBox (NULL, errStrMsgBuf, "Failed to
start executable", 
					MB_OK | MB_ICONINFORMATION);
			}

			// Free the buffer.
			LocalFree (errStrMsgBuf);
		}
		else {
			errlogPrintf ("!!WARNING!!\n");
			errlogPrintf ("Unable to locate executable
\"%s\".\n", pBaseExecutableName);
			errlogPrintf ("You may need to modify your
environment.\n");
		}
        return osiSpawnDetachedProcessFail;
	}

    return osiSpawnDetachedProcessSuccess;

	//
	// use of spawn here causes problems when the ca repeater
	// inherits open files (and sockets) from the spawning
	// process
	//
	//status = _spawnlp (_P_DETACH, pBaseExecutableName,
pBaseExecutableName, NULL);
	//if (status<0) {
	//	errlogPrintf ("!!WARNING!!\n");
	//	errlogPrintf ("Unable to locate the EPICS executable
\"%s\".\n",
	//		pBaseExecutableName);
	//	errlogPrintf ("You may need to modify your environment.\n");
	//}
}

> -----Original Message-----
> From: Mark Rivers [mailto:rivers@cars.uchicago.edu]
> Sent: Friday, September 30, 2005 3:08 PM
> To: Mark Rivers; Jeff Hill; tech-talk@aps.anl.gov
> Subject: RE: Channel access problem on cygwin IOC
> 
> Jeff,
> 
> I just learned a little more about the caRepeater problem.  When I did the
> tests in my previous message I had not run any Windows CA clients that
> would have started a Windows caRepeater task.  When I started the IOC it
> started a caRepeater task that appears with "ps -a" in cygwin, but did not
> appear in the Windows Task Manager.  I got the error saying that CA could
> not find the caRepeater.  The copy of caRepeater that was started under
> cygwin had the unfortunate property that it had a file open that my IOC
> application had opened, and that file could not be deleted until that copy
> of caRepeater was killed.
> 
> I then started medm on the Windows machine, which created a caRepeater
> task that shows up in the Windows Task Manager.  That time starting the
> IOC did not start a caRepeater task, since it must have found the one that
> was running under Windows.  However, I still got the following error at
> the IOC:
> ***
> epics> CA client library is unable to contact CA repeater a
> Silence this message by starting a CA repeater daemon
> or by calling ca_pend_event() and or ca_poll() more often.
> ****
> 
> But at least this copy of caRepeater does not have the file locked that
> needs to be deleted!
> 
> Do you understand what is going on?
> 
> Thanks,
> Mark
> 
> 
> ________________________________
> 
> From: Mark Rivers
> Sent: Fri 9/30/2005 3:33 PM
> To: Jeff Hill; tech-talk@aps.anl.gov
> Subject: RE: Channel access problem on cygwin IOC
> 
> 
> 
> Jeff,
> 
> The think the problem might have been caused by EPICS launching a second
> copy of my IOC instead of caRepeater one time.  So there were two copies
> of the IOC application running, causing the IP problem?
> 
> There is something else I don't understand about caRepeater behavior on
> this IOC.
> 
> Here is a list of cygwin processes before I start my IOC.
> $ ps -a
>       PID    PPID    PGID     WINPID  TTY  UID    STIME COMMAND
>      1364       1    1364       1364    ?   18 20:29:52 /usr/bin/cygrunsrv
>      1660    1364    1660       1672    ?   18 20:29:57 /usr/sbin/sshd
> I     460       1     460        460    0 11092 20:31:24 /usr/bin/bash
>      2280       1    2280       2280    1 11092 14:02:41 /usr/bin/bash
>      3808    2280    3808       2740    1 11092 14:03:38 /usr/bin/ps
> 
> Now I start the IOC. Note that the path to caRepeater in EPICS base is in
> my cygwin PATH.  Now list the processes again.
> 
> $ ps -a
>       PID    PPID    PGID     WINPID  TTY  UID    STIME COMMAND
>      1364       1    1364       1364    ?   18 20:29:52 /usr/bin/cygrunsrv
>      1660    1364    1660       1672    ?   18 20:29:57 /usr/sbin/sshd
>       460       1     460        460    0 11092 20:31:24 /usr/bin/bash
>      2280       1    2280       2280    1 11092 14:02:41 /usr/bin/bash
> I    2112     460    2112       3008    0 11092 14:03:49
> /cygdrive/j/epics/devel/dxp/2-4beta/bin/cygwin-x86/xmapApp
>       736    2112    2112       3284    0 11092 14:04:49
> /cygdrive/h/epics/base/bin/cygwin-x86/caRepeater
>      3932    2280    3932       3456    1 11092 15:14:12 /usr/bin/ps
> 
> 
> xmapApp is the IOC process.  Note that starting the IOC has started the
> caRepeater, as it should have.
> 
> However, I get the following message from iocsh on the IOC after iocInit
> is complete.
> *****
> CA client library is unable to contact CA repeater after 50
> Silence this message by starting a CA repeater daemon
> or by calling ca_pend_event() and or ca_poll() more often.
> ******
> 
> This does not seem right.  Why am I getting that error message even though
> caRepeater was in fact successfully started?
> 
> Thanks,
> Mark
> 




References:
RE: Channel access problem on cygwin IOC Mark Rivers

Navigate by Date:
Prev: RE: Channel access problem on cygwin IOC Mark Rivers
Next: Gateway 2.0.0.0 Released Kenneth Evans, Jr.
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  <20052006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020 
Navigate by Thread:
Prev: RE: Channel access problem on cygwin IOC Mark Rivers
Next: EPICS meeting: timetable and organization Matthias Clausen
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  <20052006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020 
ANJ, 02 Sep 2010 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· Search · EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·