1
0
mirror of https://github.com/Ylianst/MeshAgent synced 2025-12-16 00:03:45 +00:00

Fixed bug where KVM messages to parent could get interleaved

This commit is contained in:
Bryan Roe
2019-06-05 11:09:37 -07:00
parent f15c11c845
commit ffdcdbc13d

View File

@@ -63,6 +63,8 @@ int slave2master[2];
FILE *logFile = NULL; FILE *logFile = NULL;
int g_enableEvents = 0; int g_enableEvents = 0;
ILibQueue g_messageQ;
extern void* tilebuffer; extern void* tilebuffer;
extern char **environ; extern char **environ;
@@ -91,45 +93,42 @@ x11_struct *x11_exports = NULL;
void kvm_send_error(char *msg) void kvm_send_error(char *msg)
{ {
int msgLen = strnlen_s(msg, 255); int msgLen = strnlen_s(msg, 255);
char buffer[512]; char *buffer = (char*)ILibMemory_SmartAllocate(msgLen + 4);
((unsigned short*)buffer)[0] = (unsigned short)htons((unsigned short)MNG_ERROR); // Write the type ((unsigned short*)buffer)[0] = (unsigned short)htons((unsigned short)MNG_ERROR); // Write the type
((unsigned short*)buffer)[1] = (unsigned short)htons((unsigned short)(msgLen + 4)); // Write the size ((unsigned short*)buffer)[1] = (unsigned short)htons((unsigned short)(msgLen + 4)); // Write the size
memcpy_s(buffer + 4, 512 - 4, msg, msgLen); memcpy_s(buffer + 4, msgLen, msg, msgLen);
if (write(slave2master[1], buffer, msgLen + 4)) {} ILibQueue_Lock(g_messageQ);
fsync(slave2master[1]); ILibQueue_EnQueue(g_messageQ, buffer);
ILibQueue_UnLock(g_messageQ);
} }
void kvm_send_resolution() void kvm_send_resolution()
{ {
char buffer[8]; char *buffer = (char*)ILibMemory_SmartAllocate(8);
((unsigned short*)buffer)[0] = (unsigned short)htons((unsigned short)MNG_KVM_SCREEN); // Write the type ((unsigned short*)buffer)[0] = (unsigned short)htons((unsigned short)MNG_KVM_SCREEN); // Write the type
((unsigned short*)buffer)[1] = (unsigned short)htons((unsigned short)8); // Write the size ((unsigned short*)buffer)[1] = (unsigned short)htons((unsigned short)8); // Write the size
((unsigned short*)buffer)[2] = (unsigned short)htons((unsigned short)SCREEN_WIDTH); // X position ((unsigned short*)buffer)[2] = (unsigned short)htons((unsigned short)SCREEN_WIDTH); // X position
((unsigned short*)buffer)[3] = (unsigned short)htons((unsigned short)SCREEN_HEIGHT); // Y position ((unsigned short*)buffer)[3] = (unsigned short)htons((unsigned short)SCREEN_HEIGHT); // Y position
// Write the reply to the pipe. ILibQueue_Lock(g_messageQ);
//fprintf(logFile, "Writing from slave in kvm_send_resolution\n"); ILibQueue_EnQueue(g_messageQ, buffer);
if (write(slave2master[1], buffer, 8)) {} ILibQueue_UnLock(g_messageQ);
fsync(slave2master[1]);
//fprintf(logFile, "Written %d bytes to master in kvm_send_resolution\n", written);
} }
void kvm_send_display() void kvm_send_display()
{ {
char buffer[5]; char* buffer = (char*)ILibMemory_SmartAllocate(5);
((unsigned short*)buffer)[0] = (unsigned short)htons((unsigned short)MNG_KVM_SET_DISPLAY); // Write the type ((unsigned short*)buffer)[0] = (unsigned short)htons((unsigned short)MNG_KVM_SET_DISPLAY); // Write the type
((unsigned short*)buffer)[1] = (unsigned short)htons((unsigned short)5); // Write the size ((unsigned short*)buffer)[1] = (unsigned short)htons((unsigned short)5); // Write the size
buffer[4] = current_display; // Display number buffer[4] = current_display; // Display number
// Write the reply to the pipe. ILibQueue_Lock(g_messageQ);
//fprintf(logFile, "Writing from slave in kvm_send_display\n"); ILibQueue_EnQueue(g_messageQ, buffer);
if (write(slave2master[1], buffer, 5)) {} ILibQueue_UnLock(g_messageQ);
fsync(slave2master[1]);
//fprintf(logFile, "Written %d bytes to master in kvm_send_display\n", written);
} }
#define BUFSIZE 65535 #define BUFSIZE 65535
@@ -242,7 +241,7 @@ void kvm_send_display_list()
getAvailableDisplays(&displays, &len); getAvailableDisplays(&displays, &len);
totalSize = 2 /*Type*/ + 2 /*length of packet*/ + 2 /*length of data*/ + (len * 2) /*Data*/ + 2 /* Current display */; totalSize = 2 /*Type*/ + 2 /*length of packet*/ + 2 /*length of data*/ + (len * 2) /*Data*/ + 2 /* Current display */;
if ((buffer = (char*)malloc(totalSize)) == NULL) ILIBCRITICALEXIT(254); buffer = (char*)ILibMemory_SmartAllocate(totalSize);
((unsigned short*)buffer)[0] = (unsigned short)htons((unsigned short)MNG_KVM_GET_DISPLAYS); // Write the type ((unsigned short*)buffer)[0] = (unsigned short)htons((unsigned short)MNG_KVM_GET_DISPLAYS); // Write the type
((unsigned short*)buffer)[1] = (unsigned short)htons((unsigned short)totalSize); // Write the size ((unsigned short*)buffer)[1] = (unsigned short)htons((unsigned short)totalSize); // Write the size
@@ -252,13 +251,9 @@ void kvm_send_display_list()
} }
((unsigned short*)buffer)[i + 3] = (unsigned short)htons((unsigned short)current_display); // Current display ((unsigned short*)buffer)[i + 3] = (unsigned short)htons((unsigned short)current_display); // Current display
// Write the reply to the pipe. ILibQueue_Lock(g_messageQ);
//fprintf(logFile, "Writing from slave in kvm_send_displays\n"); ILibQueue_EnQueue(g_messageQ, buffer);
if (write(slave2master[1], buffer, totalSize)) {} ILibQueue_UnLock(g_messageQ);
fsync(slave2master[1]);
//fprintf(logFile, "Written %d bytes to master in kvm_send_displays\n", written);
if (displays != NULL) free(displays);
} }
char Location_X11LIB[NAME_MAX]; char Location_X11LIB[NAME_MAX];
@@ -506,14 +501,15 @@ void kvm_pause(int pause)
void kvm_server_jpegerror(char *msg) void kvm_server_jpegerror(char *msg)
{ {
int msgLen = strnlen_s(msg, 255); int msgLen = strnlen_s(msg, 255);
char buffer[512]; char *buffer = (char*)ILibMemory_SmartAllocate(msgLen + 4);
((unsigned short*)buffer)[0] = (unsigned short)htons((unsigned short)MNG_ERROR); // Write the type ((unsigned short*)buffer)[0] = (unsigned short)htons((unsigned short)MNG_ERROR); // Write the type
((unsigned short*)buffer)[1] = (unsigned short)htons((unsigned short)(msgLen + 4)); // Write the size ((unsigned short*)buffer)[1] = (unsigned short)htons((unsigned short)(msgLen + 4)); // Write the size
memcpy_s(buffer + 4, 512 - 4, msg, msgLen); memcpy_s(buffer + 4, msgLen, msg, msgLen);
if (write(slave2master[1], buffer, msgLen + 4)) {} ILibQueue_Lock(g_messageQ);
fsync(slave2master[1]); ILibQueue_EnQueue(g_messageQ, buffer);
ILibQueue_UnLock(g_messageQ);
} }
void* kvm_server_mainloop(void* parm) void* kvm_server_mainloop(void* parm)
@@ -553,6 +549,7 @@ void* kvm_server_mainloop(void* parm)
} }
} }
g_messageQ = ILibQueue_Create();
// Init the kvm // Init the kvm
//fprintf(logFile, "Before kvm_init.\n"); fflush(logFile); //fprintf(logFile, "Before kvm_init.\n"); fflush(logFile);
@@ -564,21 +561,20 @@ void* kvm_server_mainloop(void* parm)
pthread_create(&kvmthread, NULL, kvm_mainloopinput, parm); pthread_create(&kvmthread, NULL, kvm_mainloopinput, parm);
//fprintf(logFile, "Created the kvmthread.\n"); fflush(logFile); //fprintf(logFile, "Created the kvmthread.\n"); fflush(logFile);
while (!g_shutdown) { while (!g_shutdown)
{
/* // Check if there are pending messages to be sent
//printf("KVM/Loop"); ILibQueue_Lock(g_messageQ);
ftime(&tp); while (ILibQueue_IsEmpty(g_messageQ) == 0)
cur_timestamp = tp.time * 1000 + tp.millitm;
if (prev_timestamp != 0)
{ {
time_diff = (FRAME_RATE_TIMER - (cur_timestamp - prev_timestamp)); if ((buf = (char*)ILibQueue_DeQueue(g_messageQ)) != NULL)
if (time_diff < 20) { time_diff = 20; } {
written = write(slave2master[1], buf, ILibMemory_Size(buf));
fsync(slave2master[1]);
ILibMemory_Free(buf);
}
} }
usleep(time_diff * 1000); ILibQueue_UnLock(g_messageQ);
prev_timestamp = cur_timestamp;
//printf("...\n");
*/
for (r = 0; r < TILE_HEIGHT_COUNT; r++) { for (r = 0; r < TILE_HEIGHT_COUNT; r++) {
for (c = 0; c < TILE_WIDTH_COUNT; c++) { for (c = 0; c < TILE_WIDTH_COUNT; c++) {
@@ -713,6 +709,7 @@ void* kvm_server_mainloop(void* parm)
g_tileInfo = NULL; g_tileInfo = NULL;
} }
if(tilebuffer != NULL) { free(tilebuffer); tilebuffer = NULL; } if(tilebuffer != NULL) { free(tilebuffer); tilebuffer = NULL; }
ILibQueue_Destroy(g_messageQ);
return (void*)0; return (void*)0;
} }
@@ -751,6 +748,12 @@ void* kvm_relay_restart(int paused, void *processPipeMgr, ILibKVM_WriteHandler w
r = pipe(slave2master); r = pipe(slave2master);
r = pipe(master2slave); r = pipe(master2slave);
// Two Phase is ok here, because all our fork/vfork calls always happen on the same thread
fcntl(slave2master[0], F_SETFD, FD_CLOEXEC);
fcntl(slave2master[1], F_SETFD, FD_CLOEXEC);
fcntl(master2slave[0], F_SETFD, FD_CLOEXEC);
fcntl(master2slave[1], F_SETFD, FD_CLOEXEC);
slave_out = ILibProcessPipe_Pipe_CreateFromExistingWithExtraMemory(processPipeMgr, slave2master[0], 2 * sizeof(void*)); slave_out = ILibProcessPipe_Pipe_CreateFromExistingWithExtraMemory(processPipeMgr, slave2master[0], 2 * sizeof(void*));
((void**)ILibMemory_Extra(slave_out))[0] = writeHandler; ((void**)ILibMemory_Extra(slave_out))[0] = writeHandler;
((void**)ILibMemory_Extra(slave_out))[1] = reserved; ((void**)ILibMemory_Extra(slave_out))[1] = reserved;