Poll(2) Doesn't Empty the Event Queue

Blocking Queue poll method retuns null during multiple threads


When blockingqueue.poll() is being executed, there are times data is still not loaded by the repositorythread. By the time the next if block comes, blocking queue is empty and future is completed so control gets out of while loop.

You have a race condition in your code which is complicating matters:

if (blockingqueue.isEmpty() && /* race here */ future.isDone() && future.get()) {

There is a possibility that the blockingqueue.isEmpty() returns true and then the job finishes before the future.isDone() call happens causing the code to quit prematurely with an element left in the queue.

An "end of stream" object that @Willis mentioned is a good option but a simple solution would be to refactor your code like:

boolean futureDone = future.isDone();
entity = blockingqueue.poll();
if (entity == null) {
if (futureDone) {
break;
}
} else {
// process entity
}

This ensures that you always check to see if the future is done before getting the last item from the blocking-queue which removes the race. You might have to do a poll one more time but that fine.

Btw, if this code is really spinning, you should put some sort of timeout in poll to slow it down and not eat a CPU:

entity = blockingqueue.poll(50, TimeUnit.MILLISECONDS);

How do I empty the SDL event queue?

The following solution, inspired by Zammalad's comment seems to work. When no key down event is found we remove one event (typically a mouse event) from the queue to make room for new events. To make the code more robust I have also replaced the scalar event with the array events.

#define LEN(a) ((int) (sizeof (a) / sizeof (a)[0]))

static int KeyPressed(void)
{
SDL_Event events[1];
int count, result;

result = 0;
SDL_PumpEvents();
/*search the event queue for key down events*/
count = SDL_PeepEvents(events, LEN(events), SDL_PEEKEVENT, SDL_EVENTMASK(SDL_KEYDOWN));
switch (count) {
case -1:
fprintf(stderr, "SDL_PeepEvents: %s\n", SDL_GetError());
break;
case 0:
/*make room for new events by removing (non-key down) event from the queue*/
count = SDL_PeepEvents(events, LEN(events), SDL_GETEVENT, -1);
if ((count > 0) && (events[0].type == SDL_QUIT)) {
exit(EXIT_SUCCESS);
}
break;
case 1:
result = 1;
break;
}
return result;
}

AWS SQS Long Polling doesn't reduce empty receives

Actually Long Polling is working in your situation.

5 lambdas * polling / 20 seconds * 3600 seconds in an hour = 900 receives/hour

What I think you've missed is the "5 minimum concurrent lambdas". This is implied in the Lambda Scaling Behaviour documentation, but is more helpfully and explicitly laid out in the "Additional Information" section of the announcement/deep-dive blog.

When an SQS event source mapping is initially created and enabled, or
when messages first appear after a period with no traffic, then the
Lambda service will begin polling the SQS queue using five parallel
long-polling connections. The Lambda service monitors the number of
inflight messages, and when it detects that this number is trending
up, it will increase the polling frequency by 20 ReceiveMessage
requests per minute and the function concurrency by 60 calls per
minute.

SDL_Event.type always empty after polling

That nothing happens is a result of the missing case in front of SDL_KEYDOWN.

With case missing the compiler sees a jump label which you would use for e.g. goto SDL_KEYDOWN;, which results in the default label being the only label in the switch statement.

I don't see why event.type doesn't get output though unless you set some stream-flags somewhere.

event.type is an Uint8 which SDL just typedefs from integral types, so it should be handled like one. Like any integral type it also can't be "empty", but the output for it can be.

Why does the function in the event polling loop trigger less frequently than the function outside it

Your keydown event is simply fired less frequently than your game logic is updated.

A common solution is to keep track of the keyboard's state.

SDL way

I suggest storing the keyboard state as an array of booleans, which size is the number of keys you will check against, e.g. bool[SDL_KEYLAST].
So you'll have to modify it whenever an event is fired. Finally, at each loop, check for the saved keyboard state.
Example code:

handleInput()
{
while(pollEvent(&ev))
{
if(event.type = keydown)
ks[event.key.symbol] = true;
else if(event.type = keyup)
ks[event.key.symbol] = false;
}
}

update()
{
if(ks[KEY_R]) cube.rotation += 0.05f;
}

SDL2 way

const Uint8* ks = SDL_GetKeyboardState(NULL).

This function returns the keyboard state array, which is not a bool[] but a Uint8[] containing 0/1 values (so you can still check on false/true values).

But also, you'll have to check against SDL_Scancode index values if you want to use that array, which are listed here: https://wiki.libsdl.org/SDL_Scancode

handleinput()
{
//pump events so that SDL can update the keyboard state array...
}

update()
{
const Uint8* ks = SDL_GetKeyboardState(NULL);
if(ks[SDL_SCANCODE_R]) cube.rotation += 0.05f;
}

Reference: https://wiki.libsdl.org/SDL_GetKeyboardState

use poll() timeout only for new data on socket

Probably been answered in the linked posts, but the basic idea is that the poll, select, and other mechanisms do not tell you when there is new data on the socket. As you mention correctly, they only tell you when a read() would not block.

You may use EPOLLET with Linux's epoll(7) interface (other systems might have other equivalents) to do what you want; however keep in mind this is not portable.

The correct and accepted design is to either consume the network buffer fully, keep partial messages in a application-defined buffer (i.e. not in the socket's buffer) and keep track of how much additional data you need to read from the network.



Related Topics



Leave a reply



Submit