EPICS Home

Experimental Physics and Industrial Control System


 
1994  1995  1996  1997  1998  1999  <20002001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024  Index 1994  1995  1996  1997  1998  1999  <20002001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
<== Date ==> <== Thread ==>

Subject: Re: Python/CA
From: Noboru Yamamoto <[email protected]>
To: [email protected]
Cc: "[email protected]" <[email protected]>
Date: Thu, 03 Feb 2000 17:38:20 +0900
Janousch Markus wrote:
> 
> Noboru Yamamoto wrote:
> >
> > Janousch Markus wrote:
> > >
> > >
> > ca_test.Simple class gives a chance to CA library using pendio() to establish
> > connection, however, it does not check it before get() call.
> >
> > >def wait_conn(self,wait=5,dt=0.05):
> > As you see, wait_conn() has default values of wait=5,dt=0.05. If network
> > condition is
> > too bad or IOC is working very busy, even wait_conn() may raise ECA_BADCHID.
> >
> > > class Simple(ca.channel,Frame):
> > >       def __init__(self,name,master=None,*cnf):
> > >               Frame.__init__(self,master)
> > >               self.pack(expand=1,fill='both')
> > >               ca.channel.__init__(self,name);self.pendio(1.0)
> >                                          ^^^^^^^^^^^^^^^^^
> > >               self.get();self.pend_event(1.0)
> > >               .....
> >
>  Strange enough, the above call to self.pendio(1.0) before get() in the
> class Simple does not seem to work. Either I have to replace it with a
> call to wait_conn(), or with a call to pend_event(1.0). The latter two
> always seem to work. Also, when the call to pend_event(1.0) after the
> call to get() is replaced by pendio(1.0) it does not work anymore.

Now I know what happens.
"EPICS Channel Access Reference" says,
" ca_pend_io() flushes the send buffer and then wait until outstanding
queries complete
or the specified time out expires. At this time queries include calls to
ca_get() and
call to ca_search() WHICH DON'T specify a connection handler."

The creation method of ca.channel , ca.channel.__init__, set a
connection callback 
by default. So, pend_io will not wait for the completion of search_and_connect.

.get() also uses ca_array_get_callback() function internally.  You need
to call pend_event()
rather than pend_io().

In conclusion, I should have replace pend_io() call in "class Simple" by
pend_event() call.
Thank you for pointed it out.  
> 
> > __init__ has a optional argument cb. A function , which has no
> > arugument, will be called when channel connection complete. Because it
> > use CA library, you need to call
> > pend_event() or pendio() for this callback to happen. (Tk mainloop
> > calles pend_event()
> > automatically if you use -DWITH_TK option to compile _ca.c)
> >
>  When does this automatic call happen?

In _ca.c, Py_ca_fd_register() is registered as a file descriptor
registration function
using ca_add_fd_registraion() call in EPICS-CA library.
This file descriptor registration function will be called whenever CA
library creates
a new socket with a file descriptor of the new socket. 
Py_ca_fd_register will register this file descriptor to the Tk-event
loop. 
Tk event loop checks if this file descriptor has data for input/output and
calls Py_ca_service() when data is available.

> static void Py_ca_fd_register(void *pfdctx, int fd, int condition)
> {
> #if defined(WITH_TK) && ! defined(WITH_THREAD)
>   if(condition){
>     Tk_CreateFileHandler(fd, TK_READABLE, Py_ca_service, pfdctx);
>   }
>   else{
>     Tk_DeleteFileHandler(fd);
>   }
> #endif
> }

> 
> > I'm reading Python/C API reference to make _ca.c work with Python thread.
> >
>  I stay tuned and good luck!
Although Python supports threads, it interpreter is not 100% thread safe.
Tcl/Tk was not 100% thread safe before, which is also supported by Python.
CA is not thread safe on Unix (may be I am wrong).

So I need to put may Lock/Unlock statements to protect these three libraries.
I have managed to compile Python/CA with Tkinter on the CPU supporting thread(
Digital Unix v4). However, I cannot use Tk_CreateFileHandler/
Tk_DeleteFileHandler in C-level.
I need to register these function in Python level, as show below.

========== ========== ========== ========== ========== ==========
def ca_service(*arg,**kw):
    ca.pend_event(0.0001)

def ca_fd_register(arg, fd, condition):
    if condition:
        Tkinter.tkinter.createfilehandler(fd,Tkinter.READABLE, ca_service)
    else:
        Tkinter.tkinter.deletefilehandler(fd)

ca.add_fd_registration(ca_fd_register, "ca_register")
========== ========== ========== ========== ========== ==========

> 
>   Markus

Thank you for listening.

Noboru


Replies:
RE: Python/CA Jeff Hill
References:
Re: Python/CA Noboru Yamamoto

Navigate by Date:
Prev: unbundled sequencer v1.9.4 is available William Lupton
Next: Re: VxWorks global variable device support Benjamin Franksen
Index: 1994  1995  1996  1997  1998  1999  <20002001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
Navigate by Thread:
Prev: Re: Python/CA Noboru Yamamoto
Next: RE: Python/CA Jeff Hill
Index: 1994  1995  1996  1997  1998  1999  <20002001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024