Merged changes from 3.14 branch to revno 12590

This commit is contained in:
Andrew Johnson
2015-07-13 13:05:33 -05:00
7 changed files with 79 additions and 27 deletions

View File

@@ -14,6 +14,14 @@
<h2 align="center">Changes between 3.15.2 and 3.15.3</h2>
<!-- Insert new items immediately below here ... -->
<h3>Clean up after GNU readline()</h3>
<p>If EPICS Base is built with readline support, any IOC that calls epicsExit()
from a thread other than the main thread is likely to leave the user's terminal
in a weird state, requiring the user to run something like 'stty sane' to clean
it up. This release patches the readline support code to clean up automatically
by registering an epicsAtExit() routine.</p>
<h3>Removed the last vestiges of RSET::get_value()</h3>
<p>The IOC has not called the get_value() routine in the RSET for a very long

View File

@@ -209,6 +209,7 @@ $Date$</span></small></p>
<li><a href="#ca_pend_event">ca_poll</a></li>
<li><a href="#ca_puser">ca_puser</a></li>
<li><a href="#ca_put">ca_put</a></li>
<li><a href="#ca_put">ca_put_callback</a></li>
<li><a href="#ca_set_puser">ca_set_puser</a></li>
<li><a href="#ca_signal">ca_signal</a></li>
<li><a href="#ca_sg_block">ca_sg_block</a></li>
@@ -223,7 +224,7 @@ $Date$</span></small></p>
<li><a href="#ca_test_io">ca_test_io</a></li>
<li><a href="#ca_write_access">ca_write_access</a></li>
<li><a href="#ca_state">channel_state</a></li>
<li><a href="#dbr_size[]">dbr_size[]</a></li>
<li><a href="#dbr_size">dbr_size[]</a></li>
<li><a href="#dbr_size_n">dbr_size_n</a></li>
<li><a href="#dbr_value_size">dbr_value_size[]</a></li>
<li><a href="#dbr_type_t">dbr_type_to_text</a></li>
@@ -3831,7 +3832,7 @@ specified channel and boolean false otherwise.</p>
channel and boolean false otherwise</dd>
</dl>
<h3><code><a name="dbr_size[]">dbr_size[]</a></code></h3>
<h3><code><a name="dbr_size">dbr_size[]</a></code></h3>
<pre>#include &lt;db_access.h&gt;
extern unsigned dbr_size[/* TYPE */];</pre>
@@ -3953,11 +3954,12 @@ int ca_sg_create ( CA_SYNC_GID *PGID );</pre>
<p>A synchronous group can be used to guarantee that a set of channel access
requests have completed. Once a synchronous group has been created then channel
access get and put requests may be issued within it using <code>ca_sg_get()</code> and
<code>ca_sg_put()</code> respectively. The routines <code>ca_sg_block()</code> and <code>ca_sg_test()</code> can be
access get and put requests may be issued within it using
<code>ca_sg_array_get()</code> and <code>ca_sg_array_put()</code> respectively.
The routines <code>ca_sg_block()</code> and <code>ca_sg_test()</code> can be
used to block for and test for completion respectively. The routine
<code>ca_sg_reset()</code> is used to discard knowledge of old requests which have timed out
and in all likelihood will never be satisfied.</p>
<code>ca_sg_reset()</code> is used to discard knowledge of old requests which
have timed out and in all likelihood will never be satisfied.</p>
<p>Any number of asynchronous groups can have application requested operations
outstanding within them at any given time.</p>
@@ -4131,16 +4133,20 @@ status = ca_sg_reset(gid);</pre>
<h3><code><a name="ca_sg_put">ca_sg_array_put()</a></code></h3>
<pre>#include &lt;cadef.h&gt;
int ca_sg_put ( CA_SYNC_GID GID, chtype TYPE,
chid CHID, void *PVALUE );
int ca_sg_array_put ( CA_SYNC_GID GID, chtype TYPE,
unsigned long COUNT, chid CHID, void *PVALUE );</pre>
<p>Write a value, or array of values, to a channel and increment the
outstanding request count of a synchronous group. The <code>ca_sg_array_put()</code>
functionality is implemented using <code>ca_array_put_callback()</code>.</p>
<p>Write a value, or array of values, to a channel and increment the outstanding
request count of a synchronous group. The <code>ca_sg_put()</code> and
<code>ca_sg_array_put()</code> functionality is implemented using
<code>ca_array_put_callback()</code>.</p>
<p>All remote operation requests such as the above are accumulated (buffered)
and not forwarded to the server until one of <code>ca_flush_io()</code>, <code>ca_pend_io()</code>,
<code>ca_pend_event()</code>, or <code>ca_sg_block()</code> are called. This allows several requests to be
and not forwarded to the server until one of <code>ca_flush_io()</code>,
<code>ca_pend_io()</code>, <code>ca_pend_event()</code>, or
<code>ca_sg_block()</code> are called. This allows several requests to be
efficiently sent in one message.</p>
<p>If a connection is lost and then resumed outstanding puts are not
@@ -4193,6 +4199,8 @@ reissued.</p>
<h3><code><a name="ca_sg_get">ca_sg_array_get()</a></code></h3>
<pre>#include &lt;cadef.h&gt;
int ca_sg_get ( CA_SYNC_GID GID, chtype TYPE,
chid CHID, void *PVALUE );
int ca_sg_array_get ( CA_SYNC_GID GID,
chtype TYPE, unsigned long COUNT,
chid CHID, void *PVALUE );</pre>
@@ -4200,16 +4208,19 @@ int ca_sg_array_get ( CA_SYNC_GID GID,
<h4>Description</h4>
<p>Read a value from a channel and increment the outstanding request count of a
synchronous group. The <code>ca_sg_array_get()</code> functionality is implemented using
synchronous group. The <code>ca_sg_get()</code> and
<code>ca_sg_array_get()</code> functionality is implemented using
<code>ca_array_get_callback()</code>.</p>
<p>The values written into your program's variables by <code>ca_sg_get()</code> should not be
referenced by your program until ECA_NORMAL has been received from <code>ca_sg_block()</code>,
or until <code>ca_sg_test()</code> returns ECA_IODONE.</p>
<p>The values written into your program's variables by <code>ca_sg_get()</code>
or <code>ca_sg_array_get()</code> should not be referenced by your program until
ECA_NORMAL has been received from <code>ca_sg_block()</code>, or until
<code>ca_sg_test()</code> returns ECA_IODONE.</p>
<p>All remote operation requests such as the above are accumulated (buffered)
and not forwarded to the server until one of <code>ca_flush_io()</code>, <code>ca_pend_io()</code>,
<code>ca_pend_event()</code>, or <code>ca_sg_block()</code> are called. This allows several requests to be
and not forwarded to the server until one of <code>ca_flush_io()</code>,
<code>ca_pend_io()</code>, <code>ca_pend_event()</code>, or
<code>ca_sg_block()</code> are called. This allows several requests to be
efficiently sent in one message.</p>
<p>If a connection is lost and then resumed outstanding gets are not

View File

@@ -233,6 +233,17 @@ static void dbtpnCallFunc(const iocshArgBuf *args)
static const iocshFuncDef dbNotifyDumpFuncDef = {"dbNotifyDump",0,0};
static void dbNotifyDumpCallFunc(const iocshArgBuf *args) { dbNotifyDump();}
/* dbPutAttribute */
static const iocshArg dbPutAttrArg0 = { "record type",iocshArgString};
static const iocshArg dbPutAttrArg1 = { "attribute name",iocshArgString};
static const iocshArg dbPutAttrArg2 = { "value",iocshArgString};
static const iocshArg * const dbPutAttrArgs[] =
{&dbPutAttrArg0, &dbPutAttrArg1, &dbPutAttrArg2};
static const iocshFuncDef dbPutAttrFuncDef =
{"dbPutAttribute",3,dbPutAttrArgs};
static void dbPutAttrCallFunc(const iocshArgBuf *args)
{ dbPutAttribute(args[0].sval,args[1].sval,args[2].sval);}
/* tpn */
static const iocshArg tpnArg0 = { "record name",iocshArgString};
static const iocshArg tpnArg1 = { "value",iocshArgString};
@@ -405,6 +416,7 @@ void dbIocRegister(void)
iocshRegister(&pftFuncDef,pftCallFunc);
iocshRegister(&dbtpnFuncDef,dbtpnCallFunc);
iocshRegister(&dbNotifyDumpFuncDef,dbNotifyDumpCallFunc);
iocshRegister(&dbPutAttrFuncDef,dbPutAttrCallFunc);
iocshRegister(&tpnFuncDef,tpnCallFunc);
iocshRegister(&dblsrFuncDef,dblsrCallFunc);
iocshRegister(&dbLockShowLockedFuncDef,dbLockShowLockedCallFunc);

View File

@@ -132,7 +132,7 @@ const char *initHookName(int state)
"initHookAfterInterruptAccept",
"initHookAtEnd"
};
if (state < 0 || state > NELEMENTS(stateName)) {
if (state < 0 || state >= NELEMENTS(stateName)) {
return "Not an initHookState";
}
return stateName[state];

View File

@@ -309,11 +309,11 @@ static void getMaxRangeValues(short field_type, double *pupper_limit,
{
switch(field_type){
case DBF_CHAR:
*pupper_limit = -128.0;
*plower_limit = 127.0;
*pupper_limit = (double) CHAR_MAX;
*plower_limit = (double) CHAR_MIN;
break;
case DBF_UCHAR:
*pupper_limit = 255.0;
*pupper_limit = (double) UCHAR_MAX;
*plower_limit = 0.0;
break;
case DBF_SHORT:

View File

@@ -1198,7 +1198,7 @@ long dbPutRecordAttribute(
pnew = dbCalloc(1,sizeof(dbRecordAttribute));
if(pattribute) {
ellInsert(&precordType->attributeList,&pattribute->node,
ellInsert(&precordType->attributeList,pattribute->node.previous,
&pnew->node);
} else {
ellAdd(&precordType->attributeList,&pnew->node);
@@ -1232,11 +1232,16 @@ long dbGetAttributePart(DBENTRY *pdbentry, const char **ppname)
size_t nameLen = strlen(pattribute->name);
int compare = strncmp(pattribute->name, pname, nameLen);
int ch = pname[nameLen];
if (compare == 0 && !(ch == '_' || isalnum(ch))) {
pdbentry->pflddes = pattribute->pdbFldDes;
pdbentry->pfield = pattribute->value;
*ppname = &pname[nameLen];
return 0;
if (compare == 0) {
if (!(ch == '_' || isalnum(ch))) {
pdbentry->pflddes = pattribute->pdbFldDes;
pdbentry->pfield = pattribute->value;
*ppname = &pname[nameLen];
return 0;
}
if (strlen(pname) > nameLen) {
compare = -1;
}
}
if (compare >= 0) break;
pattribute = (dbRecordAttribute *)ellNext(&pattribute->node);

View File

@@ -14,6 +14,7 @@
#define epicsExportSharedSymbols
#include "envDefs.h"
#include "epicsExit.h"
#include "epicsReadline.h"
#define EPICS_COMMANDLINE_LIBRARY_EPICS 0
@@ -84,6 +85,14 @@ struct readlineContext {
char *line;
};
static enum {rlNone, rlIdle, rlBusy} rlState = rlNone;
static void rlExit(void *dummy) {
if (rlState == rlBusy)
rl_cleanup_after_signal();
}
/*
* Create a command-line context
*/
@@ -92,6 +101,11 @@ epicsReadlineBegin(FILE *in)
{
struct readlineContext *readlineContext;
if (rlState == rlNone) {
epicsAtExit(rlExit, NULL);
rlState = rlIdle;
}
readlineContext = malloc(sizeof *readlineContext);
if (readlineContext != NULL) {
readlineContext->in = in;
@@ -124,7 +138,9 @@ epicsReadline (const char *prompt, void *context)
free (readlineContext->line);
readlineContext->line = NULL;
if (readlineContext->in == NULL) {
rlState = rlBusy;
line = readline (prompt);
rlState = rlIdle;
}
else {
line = (char *)malloc (linesize * sizeof *line);