473,321 Members | 1,708 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,321 software developers and data experts.

Issues with concurrent pieces of code

Hi all,

I have a fairly complex "feed" application that recieves messages from
an external user-supplied API via a callback function, and attempts to
forward these messages to another application via TCP/IP. To handle
the different rates of communication between the two external sources,
a simple FIFO circular buffer is used, the class definition for which
is below.

This all works fine, EXCEPT when the app receives a message from the
external source at the same time as it is sending messages back to the
other application. Then, the messages from the external source
continue to be buffered up (until the buffer becomes full and circles
around), but the loop that is sending the messages back grinds to a
halt.

To check that the problem wasn't being caused by two bits of code
using the same buffer at the same time (even though the buffer's
structure means it should be able to handle a message being appended
to the tail while reading from the head), I have now implemented two
identical buffers, and two pointers to those buffers. One acts as the
"write" buffer, while the other is the "read" buffer. Data is only
read from the "read" buffer if it is not empty. When messages show up
from the external source, they are written to the "write" buffer. To
keep the connection between the two apps alive, each app sends a short
"no data" message and waits for the appropriate response from the
other end before sending another one. When my app receives a "no
data" message, it swaps the read/write buffers around, checks for data
in the new read buffer (formerly the write buffer, so it should have
some data in it), and loops around sending these messages back until
the buffer is empty, and then it sends its "no data" message. And so
on....

The app keeps a log file, and using this to insert time stamps when it
sends messages back, I can see where it is grinding to a halt (inside
the do/while loop that calls sendDataToGKServer()).

Here are the buffer definitions:

#define EXCH_BUFFER_SIZE 100

FIFOBuffer ExchangeBuffer1(EXCH_BUFFER_SIZE);
FIFOBuffer ExchangeBuffer2(EXCH_BUFFER_SIZE);
FIFOBuffer *WriteBuffer_p;
FIFOBuffer *ReadBuffer_p;

ReadBuffer_p = &ExchangeBuffer1;
WriteBuffer_p = &ExchangeBuffer2;

int active = 1;

Here is the code that is executed when a "no data" message is
received:

if (active == 1)
{
ReadBuffer_p = &ExchangeBuffer1;
WriteBuffer_p = &ExchangeBuffer2;
WriteBuffer_p->reset();
active = 2;
logFile << logTime() << "ActiveBuffer: " << active << endl;
logFile << "Size of Active Buffer: " << WriteBuffer_p-
>getSize() <<
endl;
}

else
{
ReadBuffer_p = &ExchangeBuffer2;
WriteBuffer_p = &ExchangeBuffer1;
WriteBuffer_p->reset();
active = 1;
logFile << logTime() << "ActiveBuffer: " << active << endl;
logFile << "Size of Active Buffer: " << WriteBuffer_p-
>getSize() <<
endl;

}

if (ReadBuffer_p->isEmpty() == false)
{
do
{
logFile << "Size of Read Buffer: " << ReadBuffer_p-
>getSize() <<
endl;
sendDataToGKServer(ReadBuffer_p->remove());
} while (ReadBuffer_p->isEmpty() == false);

}

The class definition for each buffer is as follows (genGKTxn_t is a
general message structure I have defined, and is expected by
sendDataToGKServer()):

class FIFOBuffer
{

public:
FIFOBuffer(int n)
{
N = n;
empty = true;
p = new genGKTxn_t[N];
first = last = 0;
}

~FIFOBuffer();

void add(genGKTxn_t* a);
genGKTxn_t* remove();
void reset() { first = last = 0; empty = true; }
int getSize() { return last - first; }
bool isEmpty() { return empty; }

private:
int N;
genGKTxn_t* p;
int first;
int last;
bool empty;
void inc_first();
void inc_last();

};

I haven't included the callback function that receives the messages
from the API as it's quite long and I don't think it's very relevant;
suffice to say that the important line is "WriteBuffer_p-
>add(gkSendRecord_p);" where gkSendRecord_p is a pointer to a pre-
filled genGKTxn_t structure.

Am I going about this in completely the wrong way? My question is
really this: why does the app grind to a halt inside that simple do/
while loop, and/or can I reasonably expect this approach to work, e.g.
should it be feasible to have code executing while also having the
potential for a callback function to fire at any time and interrupt
this code? Incidentally, I am using MSVC++ 6.0, and I have tried
compiling/linking it with single-threaded libraries and multi-threaded
libraries.

Appreciate any help/tips anyone can offer.

Regards,
-Rich

Apr 28 '07 #1
1 1345
Me
On Fri, 27 Apr 2007 19:50:39 -0700, Noone wrote:
Hi all,

I have a fairly complex "feed" application that recieves messages from
an external user-supplied API via a callback function, and attempts to
forward these messages to another application via TCP/IP. To handle the
different rates of communication between the two external sources, a
simple FIFO circular buffer is used, the class definition for which is
below.
Am I going about this in completely the wrong way? My question is
really this: why does the app grind to a halt inside that simple do/
while loop, and/or can I reasonably expect this approach to work, e.g.
should it be feasible to have code executing while also having the
potential for a callback function to fire at any time and interrupt this
code? Incidentally, I am using MSVC++ 6.0, and I have tried
compiling/linking it with single-threaded libraries and multi-threaded
libraries.
This is a bit outside the scope of comp.lang.c++ since your issue is more
algorithmic than c++ related.

I do a lot of this type of programming professionally and your solution is
going to be quite platform dependent...more so than the guys on this forum
are going to want to discuss.

I think it would be much easier if you split incoming and outgoing data
handling into two asynchronous threads with a semaphore guarded FIFO
between them. The semaphore guarding will be necessary so that operations
on the buffer remain atomic since they could possibly be attempted
concurrently by both threads.

Apr 28 '07 #2

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

16
by: JCauble | last post by:
We have a large Asp.net application that is currently crashing our production servers. What we are seeing is the aspnet_wp eat up a bunch of memory and then stop unexpectedly. Does not recycle. ...
9
by: cendrizzi | last post by:
Hi all, I've read some stuff on this but can't seem to come up with a solution that works right. I have a semi-mature (yet very large and robust) internal web application that currently only...
5
by: Tony Gravagno | last post by:
I have a class that instantiates two Timer objects that fire at different intervals. My class can be instantiated within a Windows Form or from a Windows Service. Actions performed by one of the...
18
by: Indian.croesus | last post by:
Hi, If I am right Endianness is CPU related. I do not know if the question is right in itself but if it is then how does C handle issues arising out of Endianness. I understand that if we pass...
0
by: Gerardo Herzig | last post by:
Hi all. Im having some "problems" with a small concurrent plpython function. Based on a small example about concurrent programming, there is some code which works fine under python: #!...
6
by: tenxian | last post by:
It is said as for code, developing a website that can stand 10,000 concurrent visitors is much different from developing a website that can stand 1,000 concurrent visitors, is it true?
0
by: Gabriel Genellina | last post by:
En Mon, 09 Jun 2008 15:32:00 -0300, Marcelo de Moraes Serpa <celoserpa@gmail.comescribió: I don't think it's a problem with ElementTree. Perhaps you are writing the same (global) configuration...
1
by: mrudulav | last post by:
Hi I am using Mysql 4.0.18 and executing concurrent insert statement. I am executing this statement in the loop. For first few interation the perofrmace is quite good, the query executes in...
0
amitpatel66
by: amitpatel66 | last post by:
There is always a requirement that in Oracle Applications, the Concurrent Program need to be execute programatically based on certain conditions/validations: Concurrent programs can be executed...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.