aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog2
-rw-r--r--src/IO/IO.c9
-rw-r--r--src/IO/dpi.c7
-rw-r--r--src/IO/http.c2
-rw-r--r--src/capi.c2
-rw-r--r--src/chain.c74
-rw-r--r--src/chain.h12
7 files changed, 84 insertions, 24 deletions
diff --git a/ChangeLog b/ChangeLog
index af61662e..2e88fcf3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -52,6 +52,8 @@ dillo-fltk2
- Implemented a_Dialog_choice5(). May be used by dpis and dillo.
- Improved parsing of collapsing white space.
- FTP dpi: Fixed algorithm bugs and improved the mime-type detector.
+ - CCC: added reentrancy control to the OpEnd and OpAbort operations.
+ - CCC: enhanced the debug function and implemented OpAbort for dpi.
Patches: Jorge Arellano Cid
+- Connected signals to <li> elements (fixes links within lists).
- Enabled text, background-color, panel_size, geometry, fullscreen,
diff --git a/src/IO/IO.c b/src/IO/IO.c
index f87f32e0..db3239a6 100644
--- a/src/IO/IO.c
+++ b/src/IO/IO.c
@@ -137,7 +137,7 @@ static void IO_close_fd(IOData_t *io, int CloseCode)
int st;
int events = 0;
- _MSG("====> begin IO close (%d) Key=%d CloseCode=%d Flags=%d ",
+ _MSG("====> begin IO_close_fd (%d) Key=%d CloseCode=%d Flags=%d ",
io->FD, io->Key, CloseCode, io->Flags);
/* With HTTP, if we close the writing part, the reading one also gets
@@ -157,11 +157,9 @@ static void IO_close_fd(IOData_t *io, int CloseCode)
if (CloseCode & IO_StopRd) {
events |= DIO_READ;
}
-
if (CloseCode & IO_StopWr) {
events |= DIO_WRITE;
}
-
a_IOwatch_remove_fd(io->FD, events);
_MSG(" end IO close (%d) <=====\n", io->FD);
}
@@ -213,6 +211,7 @@ static bool_t IO_read(IOData_t *io)
* may abort the whole Chain. */
if ((io = IO_get(io_key))) {
/* All data read (EOF) */
+ _MSG("IO_read: io->Key=%d io_key=%d\n", io->Key, io_key);
a_IO_ccc(OpEnd, 2, FWD, io->Info, io, NULL);
}
}
@@ -349,7 +348,7 @@ void a_IO_ccc(int Op, int Branch, int Dir, ChainLink *Info,
IOData_t *io;
DataBuf *dbuf;
- a_Chain_debug_msg("a_IO_ccc", Op, Branch, Dir);
+ dReturn_if_fail( a_Chain_check("a_IO_ccc", Op, Branch, Dir, Info) );
if (Branch == 1) {
if (Dir == BCK) {
@@ -421,7 +420,7 @@ void a_IO_ccc(int Op, int Branch, int Dir, ChainLink *Info,
break;
case OpEnd:
a_Chain_fcb(OpEnd, Info, NULL, NULL);
- IO_close_fd(io, IO_StopRdWr);
+ IO_close_fd(io, IO_StopRdWr); /* IO_StopRd would leak FDs */
IO_free(io);
dFree(Info);
break;
diff --git a/src/IO/dpi.c b/src/IO/dpi.c
index 52ee7d87..33e5f730 100644
--- a/src/IO/dpi.c
+++ b/src/IO/dpi.c
@@ -606,7 +606,7 @@ void a_Dpi_ccc(int Op, int Branch, int Dir, ChainLink *Info,
dpi_conn_t *conn;
int SockFD = -1, st;
- a_Chain_debug_msg("a_Dpi_ccc", Op, Branch, Dir);
+ dReturn_if_fail( a_Chain_check("a_Dpi_ccc", Op, Branch, Dir, Info) );
if (Branch == 1) {
if (Dir == BCK) {
@@ -641,6 +641,11 @@ void a_Dpi_ccc(int Op, int Branch, int Dir, ChainLink *Info,
dFree(Info->LocalKey);
dFree(Info);
break;
+ case OpAbort:
+ a_Chain_bcb(OpAbort, Info, NULL, NULL);
+ dFree(Info->LocalKey);
+ dFree(Info);
+ break;
default:
MSG_WARN("Unused CCC\n");
break;
diff --git a/src/IO/http.c b/src/IO/http.c
index 46a2f313..6275db3d 100644
--- a/src/IO/http.c
+++ b/src/IO/http.c
@@ -498,7 +498,7 @@ void a_Http_ccc(int Op, int Branch, int Dir, ChainLink *Info,
{
int SKey = VOIDP2INT(Info->LocalKey);
- a_Chain_debug_msg("a_Http_ccc", Op, Branch, Dir);
+ dReturn_if_fail( a_Chain_check("a_Http_ccc", Op, Branch, Dir, Info) );
if (Branch == 1) {
if (Dir == BCK) {
diff --git a/src/capi.c b/src/capi.c
index 2be5045e..70011224 100644
--- a/src/capi.c
+++ b/src/capi.c
@@ -461,7 +461,7 @@ void a_Capi_ccc(int Op, int Branch, int Dir, ChainLink *Info,
{
capi_conn_t *conn;
- a_Chain_debug_msg("a_Capi_ccc", Op, Branch, Dir);
+ dReturn_if_fail( a_Chain_check("a_Capi_ccc", Op, Branch, Dir, Info) );
if (Branch == 1) {
if (Dir == BCK) {
diff --git a/src/chain.c b/src/chain.c
index 32fd6950..354817ea 100644
--- a/src/chain.c
+++ b/src/chain.c
@@ -18,6 +18,21 @@
#define VERBOSE 0
/*
+ * Show debugging info
+ */
+static void Chain_debug_msg(char *FuncStr, int Op, int Branch, int Dir,
+ ChainLink *Info)
+{
+#if VERBOSE
+ const char *StrOps[] = {"", "OpStart", "OpSend",
+ "OpStop", "OpEnd", "OpAbort"};
+ MSG("%-*s: %-*s [%d%s] Info=%p Flags=%d\n",
+ 12, FuncStr, 7, StrOps[Op], Branch, (Dir == 1) ? "F" : "B",
+ Info, Info ? Info->Flags : -1);
+#endif
+}
+
+/*
* Create and initialize a new chain-link
*/
ChainLink *a_Chain_new(void)
@@ -79,26 +94,46 @@ void a_Chain_unlink(ChainLink *Info, int Direction)
/*
* Issue the forward callback of the 'Info' link
+ * Return value: 1 if OK, 0 if not operative.
*/
int a_Chain_fcb(int Op, ChainLink *Info, void *Data1, void *Data2)
{
- if (Info->Fcb) {
+ int ret = 0;
+
+ if (Info->Flags & (CCC_Ended + CCC_Aborted)) {
+ /* CCC is not operative */
+ } else if (Info->Fcb) {
+ if (Op == OpEnd)
+ Info->Flags |= CCC_Ended;
+ else if (Op == OpAbort)
+ Info->Flags |= CCC_Aborted;
+
Info->Fcb(Op, Info->FcbBranch, FWD, Info->FcbInfo, Data1, Data2);
- return 1;
+ ret = 1;
}
- return 0;
+ return ret;
}
/*
* Issue the backward callback of the 'Info' link
+ * Return value: 1 if OK, 0 if not operative.
*/
int a_Chain_bcb(int Op, ChainLink *Info, void *Data1, void *Data2)
{
- if (Info->Bcb) {
+ int ret = 0;
+
+ if (Info->Flags & (CCC_Ended + CCC_Aborted)) {
+ /* CCC is not operative */
+ } else if (Info->Bcb) {
+ if (Op == OpEnd)
+ Info->Flags |= CCC_Ended;
+ else if (Op == OpAbort)
+ Info->Flags |= CCC_Aborted;
+
Info->Bcb(Op, Info->BcbBranch, BCK, Info->BcbInfo, Data1, Data2);
- return 1;
+ ret = 1;
}
- return 0;
+ return ret;
}
@@ -115,14 +150,25 @@ DataBuf *a_Chain_dbuf_new(void *buf, int size, int code)
}
/*
- * Show some debugging info
+ * Check whether the CCC is operative.
+ * Also used to hook debug information.
+ *
+ * Return value: 1 if ready to use, 0 if not operative.
*/
-void a_Chain_debug_msg(char *FuncStr, int Op, int Branch, int Dir)
+int a_Chain_check(char *FuncStr, int Op, int Branch, int Dir,
+ ChainLink *Info)
{
-#if VERBOSE
- const char *StrOps[] = {"", "OpStart", "OpSend",
- "OpStop", "OpEnd", "OpAbort"};
- MSG("%-*s: %-*s [%d%s]\n",
- 12, FuncStr, 7, StrOps[Op], Branch, (Dir == 1) ? "F" : "B");
-#endif
+ int ret = 0;
+
+ /* Show status information */
+ Chain_debug_msg(FuncStr, Op, Branch, Dir, Info);
+
+ if (Info->Flags & (CCC_Ended + CCC_Aborted)) {
+ /* CCC is not operative */
+ MSG_WARN("CCC: call on already finished chain.\n");
+ } else {
+ ret = 1;
+ }
+ return ret;
}
+
diff --git a/src/chain.h b/src/chain.h
index 2d5f0aae..b6b41bd4 100644
--- a/src/chain.h
+++ b/src/chain.h
@@ -16,6 +16,12 @@
#define OpEnd 4
#define OpAbort 5
+/*
+ * CCC flags
+ */
+#define CCC_Stopped (1 << 0)
+#define CCC_Ended (1 << 1)
+#define CCC_Aborted (1 << 2)
/*
* Linking direction
@@ -33,6 +39,8 @@ typedef void (*ChainFunction_t)(int Op, int Branch, int Dir, ChainLink *Info,
struct _ChainLink {
void *LocalKey;
+ int Flags;
+
ChainLink *FcbInfo;
ChainFunction_t Fcb;
int FcbBranch;
@@ -61,9 +69,9 @@ ChainLink *a_Chain_link_new(ChainLink *AInfo, ChainFunction_t AFunc,
void a_Chain_unlink(ChainLink *Info, int Direction);
int a_Chain_fcb(int Op, ChainLink *Info, void *Data1, void *Data2);
int a_Chain_bcb(int Op, ChainLink *Info, void *Data1, void *Data2);
+int a_Chain_check(char *FuncStr, int Op, int Branch, int Dir,
+ ChainLink *Info);
DataBuf *a_Chain_dbuf_new(void *buf, int size, int code);
-void a_Chain_debug_msg(char *FuncStr, int Op, int Branch, int Dir);
-
#endif /* __CHAIN_H__ */