[GB.NET]
* BUG: SerialPort: Correctly release the polling timer when the serial port is closed. git-svn-id: svn://localhost/gambas/trunk@7579 867c0c6c-44f3-4631-809d-bfa615b0a4ec
This commit is contained in:
parent
cb5641ca98
commit
888a837352
@ -50,7 +50,7 @@
|
||||
#define MAX_SERIAL_BUFFER_SIZE 65536
|
||||
|
||||
|
||||
GB_STREAM_DESC SerialStream =
|
||||
GB_STREAM_DESC SerialStream =
|
||||
{
|
||||
open: CSerialPort_stream_open,
|
||||
close: CSerialPort_stream_close,
|
||||
@ -76,23 +76,23 @@ static SERIAL_SIGNAL get_signals(CSERIALPORT *_object)
|
||||
{
|
||||
int ist = 0;
|
||||
SERIAL_SIGNAL signals = { 0 };
|
||||
|
||||
|
||||
ioctl(THIS->port, TIOCMGET, &ist);
|
||||
|
||||
|
||||
signals.DSR = (ist & TIOCM_DSR) != 0;
|
||||
signals.DTR = (ist & TIOCM_DTR) != 0;
|
||||
signals.RTS = (ist & TIOCM_RTS) != 0;
|
||||
signals.CTS = (ist & TIOCM_CTS) != 0;
|
||||
signals.DCD = (ist & TIOCM_CAR) != 0;
|
||||
signals.RNG = (ist & TIOCM_RNG) != 0;
|
||||
|
||||
|
||||
return signals;
|
||||
}
|
||||
|
||||
static void raise_event(CSERIALPORT *_object, intptr_t event)
|
||||
{
|
||||
int val = 0;
|
||||
|
||||
|
||||
if (event == EVENT_DSR)
|
||||
val = THIS->signals.DSR;
|
||||
else if (event == EVENT_DTR)
|
||||
@ -105,7 +105,7 @@ static void raise_event(CSERIALPORT *_object, intptr_t event)
|
||||
val = THIS->signals.DCD;
|
||||
else if (event == EVENT_RNG)
|
||||
val = THIS->signals.RNG;
|
||||
|
||||
|
||||
GB.Raise(THIS, (int)event, 1, GB_T_BOOLEAN, val);
|
||||
GB.Unref(POINTER(&_object));
|
||||
}
|
||||
@ -117,7 +117,7 @@ if (THIS->signals._signal != new_signals._signal) \
|
||||
GB.Ref(THIS); \
|
||||
GB.Post2(raise_event, (intptr_t)THIS, (intptr_t)EVENT_##_signal); \
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int cb_change(intptr_t _object)
|
||||
{
|
||||
@ -131,14 +131,14 @@ static int cb_change(intptr_t _object)
|
||||
|
||||
/* Serial port signals status */
|
||||
new_signals = get_signals(THIS);
|
||||
|
||||
|
||||
CHECK_SIGNAL(DSR);
|
||||
CHECK_SIGNAL(DTR);
|
||||
CHECK_SIGNAL(RTS);
|
||||
CHECK_SIGNAL(CTS);
|
||||
CHECK_SIGNAL(DCD);
|
||||
CHECK_SIGNAL(RNG);
|
||||
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -153,7 +153,7 @@ static void assign_callback(CSERIALPORT *_object, int polling)
|
||||
|
||||
if (GB.CanRaise(THIS, EVENT_Read))
|
||||
GB.Watch(port, GB_WATCH_READ, (void *)cb_read, (intptr_t)THIS);
|
||||
|
||||
|
||||
if (GB.CanRaise(THIS, EVENT_DTR)
|
||||
|| GB.CanRaise(THIS, EVENT_CTS)
|
||||
|| GB.CanRaise(THIS, EVENT_DCD)
|
||||
@ -162,7 +162,7 @@ static void assign_callback(CSERIALPORT *_object, int polling)
|
||||
|| GB.CanRaise(THIS, EVENT_RTS))
|
||||
{
|
||||
// Polling is 50ms by default
|
||||
GB.Every(polling, cb_change, (intptr_t)THIS);
|
||||
THIS->every = GB.Every(polling, cb_change, (intptr_t)THIS);
|
||||
}
|
||||
}
|
||||
|
||||
@ -173,6 +173,12 @@ static void release_callback(CSERIALPORT *_object)
|
||||
|
||||
static void close_serial_port(CSERIALPORT *_object)
|
||||
{
|
||||
if (THIS->every)
|
||||
{
|
||||
GB.Unref(POINTER(&THIS->every));
|
||||
THIS->every = NULL;
|
||||
}
|
||||
|
||||
if (THIS->status)
|
||||
{
|
||||
release_callback(THIS);
|
||||
@ -219,9 +225,9 @@ int CSerialPort_stream_close(GB_STREAM *stream)
|
||||
{
|
||||
void *_object = stream->tag;
|
||||
|
||||
if (!_object)
|
||||
if (!_object)
|
||||
return -1;
|
||||
|
||||
|
||||
close_serial_port(THIS);
|
||||
return 0;
|
||||
}
|
||||
@ -233,7 +239,7 @@ int CSerialPort_stream_lof(GB_STREAM *stream, int64_t *len)
|
||||
|
||||
*len=0;
|
||||
if (!_object) return -1;
|
||||
|
||||
|
||||
if (ioctl(THIS->port,FIONREAD,&bytes)) return -1;
|
||||
*len = bytes;
|
||||
return 0;
|
||||
@ -245,7 +251,7 @@ int CSerialPort_stream_eof(GB_STREAM *stream)
|
||||
int bytes;
|
||||
|
||||
if (!_object) return -1;
|
||||
|
||||
|
||||
if (ioctl(THIS->port,FIONREAD,&bytes)) return -1;
|
||||
if (!bytes) return -1;
|
||||
return 0;
|
||||
@ -258,25 +264,25 @@ int CSerialPort_stream_read(GB_STREAM *stream, char *buffer, int len)
|
||||
int no_block = 0;
|
||||
int bytes;
|
||||
|
||||
if (!_object)
|
||||
if (!_object)
|
||||
return -1;
|
||||
|
||||
if (ioctl(THIS->port, FIONREAD, &bytes))
|
||||
|
||||
if (ioctl(THIS->port, FIONREAD, &bytes))
|
||||
return -1;
|
||||
|
||||
if (bytes < len)
|
||||
|
||||
if (bytes < len)
|
||||
return -1;
|
||||
|
||||
|
||||
ioctl(THIS->port, FIONBIO, &no_block);
|
||||
|
||||
|
||||
npos = read(THIS->port, (void*)buffer, len);
|
||||
|
||||
|
||||
no_block++;
|
||||
ioctl(THIS->port, FIONBIO, &no_block);
|
||||
|
||||
if (npos != len)
|
||||
|
||||
if (npos != len)
|
||||
return -1;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -286,19 +292,19 @@ int CSerialPort_stream_write(GB_STREAM *stream, char *buffer, int len)
|
||||
int npos = -1;
|
||||
int no_block = 0;
|
||||
|
||||
if (!_object)
|
||||
if (!_object)
|
||||
return -1;
|
||||
|
||||
|
||||
ioctl(THIS->port, FIONBIO, &no_block);
|
||||
|
||||
|
||||
npos = write(THIS->port, (void*)buffer, len);
|
||||
|
||||
|
||||
no_block++;
|
||||
ioctl(THIS->port, FIONBIO, &no_block);
|
||||
|
||||
if (npos < 0)
|
||||
|
||||
if (npos < 0)
|
||||
return -1;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -386,7 +392,7 @@ END_PROPERTY
|
||||
BEGIN_PROPERTY(SerialPort_RTS)
|
||||
|
||||
int ist;
|
||||
|
||||
|
||||
if (READ_PROPERTY)
|
||||
{
|
||||
if (!THIS->status)
|
||||
@ -481,14 +487,14 @@ BEGIN_PROPERTY(SerialPort_FlowControl)
|
||||
{
|
||||
if (check_close(THIS))
|
||||
return;
|
||||
|
||||
|
||||
flow = VPROP(GB_INTEGER);
|
||||
if (flow < 0 || flow > 3)
|
||||
{
|
||||
GB.Error("Invalid flow control value");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
THIS->flow = VPROP(GB_INTEGER);
|
||||
}
|
||||
|
||||
@ -499,7 +505,7 @@ END_PROPERTY
|
||||
BEGIN_PROPERTY(SerialPort_Parity)
|
||||
|
||||
int parity;
|
||||
|
||||
|
||||
if (READ_PROPERTY)
|
||||
GB.ReturnInteger(THIS->parity);
|
||||
else
|
||||
@ -513,7 +519,7 @@ BEGIN_PROPERTY(SerialPort_Parity)
|
||||
GB.Error("Invalid parity");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
THIS->parity = parity;
|
||||
}
|
||||
|
||||
@ -524,16 +530,16 @@ END_PROPERTY
|
||||
BEGIN_PROPERTY(SerialPort_Speed)
|
||||
|
||||
int speed;
|
||||
|
||||
|
||||
if (READ_PROPERTY)
|
||||
GB.ReturnInteger(THIS->speed);
|
||||
else
|
||||
{
|
||||
if (check_close(THIS))
|
||||
return;
|
||||
|
||||
|
||||
speed = VPROP(GB_INTEGER);
|
||||
|
||||
|
||||
if (ConvertBaudRate(speed) == -1)
|
||||
GB.Error("Invalid speed value");
|
||||
else
|
||||
@ -547,16 +553,16 @@ END_PROPERTY
|
||||
BEGIN_PROPERTY(SerialPort_DataBits)
|
||||
|
||||
int value;
|
||||
|
||||
|
||||
if (READ_PROPERTY)
|
||||
GB.ReturnInteger(THIS->dataBits);
|
||||
else
|
||||
{
|
||||
if (check_close(THIS))
|
||||
return;
|
||||
|
||||
|
||||
value = VPROP(GB_INTEGER);
|
||||
|
||||
|
||||
if (ConvertDataBits(value) == -1)
|
||||
GB.Error("Invalid data bits value");
|
||||
else
|
||||
@ -570,16 +576,16 @@ END_PROPERTY
|
||||
BEGIN_PROPERTY(SerialPort_StopBits)
|
||||
|
||||
int value;
|
||||
|
||||
|
||||
if (READ_PROPERTY)
|
||||
GB.ReturnInteger(THIS->stopBits);
|
||||
else
|
||||
{
|
||||
if (check_close(THIS))
|
||||
return;
|
||||
|
||||
|
||||
value = VPROP(GB_INTEGER);
|
||||
|
||||
|
||||
if (ConvertStopBits(value) == -1)
|
||||
GB.Error("Invalid stop bits value");
|
||||
else
|
||||
@ -623,14 +629,14 @@ BEGIN_METHOD(SerialPort_Open, GB_INTEGER polling)
|
||||
GB.Error("Port is already opened");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if ((err = OpenSerialPort(&THIS->port, THIS->flow, &THIS->oldtio, THIS->portName, THIS->speed, THIS->parity, THIS->dataBits, THIS->stopBits)))
|
||||
{
|
||||
sprintf(buffer, "#%d", err);
|
||||
GB.Error("Cannot open serial port (&1)", buffer);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
THIS->signals = get_signals(THIS);
|
||||
THIS->stream.desc = &SerialStream;
|
||||
THIS->stream.tag = THIS;
|
||||
@ -677,22 +683,22 @@ GB_DESC CSerialPortDesc[] =
|
||||
GB_INHERITS("Stream"),
|
||||
|
||||
GB_CONSTANT("None", "i", 0),
|
||||
|
||||
|
||||
GB_CONSTANT("Hardware", "i", 1),
|
||||
GB_CONSTANT("Software", "i", 2),
|
||||
GB_CONSTANT("Both", "i", 3),
|
||||
|
||||
GB_CONSTANT("Even", "i", 1),
|
||||
GB_CONSTANT("Odd", "i", 2),
|
||||
|
||||
|
||||
GB_CONSTANT("Bits1", "i", 1),
|
||||
GB_CONSTANT("Bits2", "i", 2),
|
||||
|
||||
|
||||
GB_CONSTANT("Bits5", "i", 5),
|
||||
GB_CONSTANT("Bits6", "i", 6),
|
||||
GB_CONSTANT("Bits7", "i", 7),
|
||||
GB_CONSTANT("Bits8", "i", 8),
|
||||
|
||||
|
||||
GB_EVENT("Read", NULL, NULL, &EVENT_Read),
|
||||
GB_EVENT("DTRChange", NULL, "(CurrentValue)b", &EVENT_DTR),
|
||||
GB_EVENT("DSRChange", NULL, "(CurrentValue)b", &EVENT_DSR),
|
||||
@ -709,7 +715,7 @@ GB_DESC CSerialPortDesc[] =
|
||||
GB_PROPERTY("PortName", "s", SerialPort_Port),
|
||||
GB_PROPERTY("Parity", "i", SerialPort_Parity),
|
||||
GB_PROPERTY("Speed", "i", SerialPort_Speed),
|
||||
|
||||
|
||||
GB_PROPERTY("DataBits", "i", SerialPort_DataBits),
|
||||
GB_PROPERTY("StopBits", "i", SerialPort_StopBits),
|
||||
GB_PROPERTY("DTR", "b", SerialPort_DTR),
|
||||
|
@ -38,7 +38,7 @@ extern GB_STREAM_DESC SerialStream;
|
||||
|
||||
#endif
|
||||
|
||||
typedef
|
||||
typedef
|
||||
struct
|
||||
{
|
||||
unsigned DSR : 1;
|
||||
@ -64,9 +64,10 @@ typedef
|
||||
int stopBits;
|
||||
int flow;
|
||||
int polling;
|
||||
GB_TIMER *every;
|
||||
SERIAL_SIGNAL signals;
|
||||
struct termios oldtio;
|
||||
}
|
||||
}
|
||||
CSERIALPORT;
|
||||
|
||||
int CSerialPort_stream_read(GB_STREAM *stream, char *buffer, int len);
|
||||
|
Loading…
x
Reference in New Issue
Block a user