Commit 25813b22 authored by Oleg Dzhimiev's avatar Oleg Dzhimiev

1. Built in glibc 2.28 and gcc 8.2.0:

  mkfifo/fopen/fread/fwrite kind of worked with glibc 2.26 and gcc 7.2.0.
  With 2.28 named-pipe reading with fread would read the pipe only once for
  some reason - probably because it stopped being a 'blocking' call
  To fix - switched to open/read/poll combination - so none of glibc functions
  is used.

2. camogm_fifo_reader - test program - use with *_writer or just 'echo'
3. camogm_fifo_writer - test program
parent 64eeb889
GUIDIR = camogmgui GUIDIR = camogmgui
PROGS = camogm PROGS = camogm
TEST_PROG = camogm_test TEST_PROG = camogm_test
TEST_PROG1 = camogm_fifo_writer
TEST_PROG2 = camogm_fifo_reader
PHPSCRIPTS = camogmstate.php $(GUIDIR)/camogmgui.php $(GUIDIR)/camogmgui.css $(GUIDIR)/camogmgui.js $(GUIDIR)/camogm_interface.php \ PHPSCRIPTS = camogmstate.php $(GUIDIR)/camogmgui.php $(GUIDIR)/camogmgui.css $(GUIDIR)/camogmgui.js $(GUIDIR)/camogm_interface.php \
$(GUIDIR)/SpryTabbedPanels.css $(GUIDIR)/SpryTabbedPanels.js $(GUIDIR)/xml_simple.php $(GUIDIR)/SpryCollapsiblePanel.css \ $(GUIDIR)/SpryTabbedPanels.css $(GUIDIR)/SpryTabbedPanels.js $(GUIDIR)/xml_simple.php $(GUIDIR)/SpryCollapsiblePanel.css \
$(GUIDIR)/SpryCollapsiblePanel.js $(GUIDIR)/SpryCollapsiblePanel.js
...@@ -13,6 +16,9 @@ IMAGES = $(GUIDIR)/images/filebrowser-01.gif $(GUIDIR)/images/filebrowser-bo ...@@ -13,6 +16,9 @@ IMAGES = $(GUIDIR)/images/filebrowser-01.gif $(GUIDIR)/images/filebrowser-bo
SRCS = camogm.c camogm_ogm.c camogm_jpeg.c camogm_mov.c camogm_kml.c camogm_read.c index_list.c camogm_align.c SRCS = camogm.c camogm_ogm.c camogm_jpeg.c camogm_mov.c camogm_kml.c camogm_read.c index_list.c camogm_align.c
TEST_SRC = camogm_test.c TEST_SRC = camogm_test.c
TEST_SRC1 = camogm_fifo_writer.c
TEST_SRC2 = camogm_fifo_reader.c
OBJS = $(SRCS:.c=.o) OBJS = $(SRCS:.c=.o)
CFLAGS += -Wall -I$(STAGING_DIR_HOST)/usr/include-uapi CFLAGS += -Wall -I$(STAGING_DIR_HOST)/usr/include-uapi
...@@ -28,17 +34,21 @@ BINDIR = /usr/bin/ ...@@ -28,17 +34,21 @@ BINDIR = /usr/bin/
WWW_PAGES = /www/pages WWW_PAGES = /www/pages
IMAGEDIR = $(WWW_PAGES)/images IMAGEDIR = $(WWW_PAGES)/images
all: $(PROGS) $(TEST_PROG) all: $(PROGS) $(TEST_PROG) $(TEST_PROG1) $(TEST_PROG2)
$(PROGS): $(OBJS) $(PROGS): $(OBJS)
$(CC) $(CFLAGS) $(LDFLAGS) $^ $(LDLIBS) -o $@ $(CC) $(CFLAGS) $(LDFLAGS) $^ $(LDLIBS) -o $@
$(TEST_PROG): $(TEST_SRC:.c=.o) $(TEST_PROG): $(TEST_SRC:.c=.o)
$(TEST_PROG1): $(TEST_SRC1:.c=.o)
$(TEST_PROG2): $(TEST_SRC2:.c=.o)
install: $(PROGS) $(PHPSCRIPTS) $(CONFIGS) install: $(PROGS) $(PHPSCRIPTS) $(CONFIGS)
$(INSTALL) $(OWN) -d $(DESTDIR)$(BINDIR) $(INSTALL) $(OWN) -d $(DESTDIR)$(BINDIR)
$(INSTALL) $(OWN) -m $(INSTMODE) $(PROGS) $(DESTDIR)$(BINDIR) $(INSTALL) $(OWN) -m $(INSTMODE) $(PROGS) $(DESTDIR)$(BINDIR)
$(INSTALL) $(OWN) -m $(INSTMODE) $(TEST_PROG) $(DESTDIR)$(BINDIR) $(INSTALL) $(OWN) -m $(INSTMODE) $(TEST_PROG) $(DESTDIR)$(BINDIR)
$(INSTALL) $(OWN) -m $(INSTMODE) $(TEST_PROG1) $(DESTDIR)$(BINDIR)
$(INSTALL) $(OWN) -m $(INSTMODE) $(TEST_PROG2) $(DESTDIR)$(BINDIR)
$(INSTALL) $(OWN) -d $(DESTDIR)$(SYSCONFDIR) $(INSTALL) $(OWN) -d $(DESTDIR)$(SYSCONFDIR)
$(INSTALL) $(OWN) -m $(INSTDOCS) $(CONFIGS) $(DESTDIR)$(SYSCONFDIR) $(INSTALL) $(OWN) -m $(INSTDOCS) $(CONFIGS) $(DESTDIR)$(SYSCONFDIR)
$(INSTALL) $(OWN) -d $(DESTDIR)$(WWW_PAGES) $(INSTALL) $(OWN) -d $(DESTDIR)$(WWW_PAGES)
......
...@@ -30,6 +30,8 @@ ...@@ -30,6 +30,8 @@
#include <ctype.h> #include <ctype.h>
#include <elphel/ahci_cmd.h> #include <elphel/ahci_cmd.h>
#include <poll.h>
#include "camogm_ogm.h" #include "camogm_ogm.h"
#include "camogm_jpeg.h" #include "camogm_jpeg.h"
#include "camogm_mov.h" #include "camogm_mov.h"
...@@ -38,6 +40,8 @@ ...@@ -38,6 +40,8 @@
/** @brief Default debug level */ /** @brief Default debug level */
#define DEFAULT_DEBUG_LVL 6 #define DEFAULT_DEBUG_LVL 6
/** @brief Default poll() timeout in ms*/
#define DEFAULT_POLL_TIMEOUT 1000
/** @brief JPEG trailer size in bytes */ /** @brief JPEG trailer size in bytes */
#define TRAILER_SIZE 0x02 #define TRAILER_SIZE 0x02
/** @brief Default segment duration in seconds */ /** @brief Default segment duration in seconds */
...@@ -1301,7 +1305,9 @@ char * getLineFromPipe(FILE* npipe) ...@@ -1301,7 +1305,9 @@ char * getLineFromPipe(FILE* npipe)
if (!cmdbufp) cmdbuf[cmdbufp] = 0; //null-terminate first access (probably not needed for the static buffer if (!cmdbufp) cmdbuf[cmdbufp] = 0; //null-terminate first access (probably not needed for the static buffer
nlp = strpbrk(cmdbuf, ";\n"); nlp = strpbrk(cmdbuf, ";\n");
if (!nlp) { //no complete string, try to read more if (!nlp) { //no complete string, try to read more
fl = fread(&cmdbuf[cmdbufp], 1, sizeof(cmdbuf) - cmdbufp - 1, npipe); // 2019/01/16: this change is related to switching to poll()
//fl = fread(&cmdbuf[cmdbufp], 1, sizeof(cmdbuf) - cmdbufp - 1, npipe);
fl = read(npipe, &cmdbuf[cmdbufp], sizeof(cmdbuf) - cmdbufp - 1);
cmdbuf[cmdbufp + fl] = 0; cmdbuf[cmdbufp + fl] = 0;
// is there any complete string in a buffer after reading? // is there any complete string in a buffer after reading?
nlp = strpbrk(&cmdbuf[cmdbufp], ";\n"); // there were no new lines before cmdbufp nlp = strpbrk(&cmdbuf[cmdbufp], ";\n"); // there were no new lines before cmdbufp
...@@ -1548,6 +1554,8 @@ int listener_loop(camogm_state *state) ...@@ -1548,6 +1554,8 @@ int listener_loop(camogm_state *state)
int curr_port = 0; int curr_port = 0;
const char *pipe_name = state->pipe_name; const char *pipe_name = state->pipe_name;
struct pollfd pfd;
// create a named pipe // create a named pipe
// always delete the pipe if it existed, start a fresh one // always delete the pipe if it existed, start a fresh one
f_ok = access(pipe_name, F_OK); f_ok = access(pipe_name, F_OK);
...@@ -1567,6 +1575,8 @@ int listener_loop(camogm_state *state) ...@@ -1567,6 +1575,8 @@ int listener_loop(camogm_state *state)
} }
} }
/* old */
/*
// now open the pipe - will block until something will be written (or just open for writing, // now open the pipe - will block until something will be written (or just open for writing,
// reads themselves will not block) // reads themselves will not block)
if (!((cmd_file = fopen(pipe_name, "r")))) { if (!((cmd_file = fopen(pipe_name, "r")))) {
...@@ -1574,6 +1584,27 @@ int listener_loop(camogm_state *state) ...@@ -1574,6 +1584,27 @@ int listener_loop(camogm_state *state)
clean_up(state); clean_up(state);
return -5; return -5;
} }
*/
/* new: 2019/01/16 */
// Adding poll() because supposedly read calls (read, fread)
// stopped being blocking at all
// Why O_RDWR?
// https://stackoverflow.com/questions/22021253/poll-on-named-pipe-returns-with-pollhup-constantly-and-immediately
if (!((cmd_file = open(pipe_name, O_RDWR|O_NONBLOCK)))) {
D0(fprintf(debug_file, "Can not open command file %s\n", pipe_name));
clean_up(state);
return -5;
}
/* force(?) disable O_NONBLOCK */
fcntl(cmd_file, F_SETFL, 0);
// ready to read
pfd.events = POLLIN;
pfd.fd = cmd_file;
D0(fprintf(debug_file, "Pipe %s open for reading\n", pipe_name)); // to make sure something is sent out D0(fprintf(debug_file, "Pipe %s open for reading\n", pipe_name)); // to make sure something is sent out
// enter main processing loop // enter main processing loop
...@@ -1581,6 +1612,14 @@ int listener_loop(camogm_state *state) ...@@ -1581,6 +1612,14 @@ int listener_loop(camogm_state *state)
curr_port = select_port(state); curr_port = select_port(state);
state->port_num = curr_port; state->port_num = curr_port;
// look at command queue first // look at command queue first
ret = poll(&pfd,1,DEFAULT_POLL_TIMEOUT);
if (ret==0){
D6(fprintf(debug_file, "Waiting for commands...\n"));
}
if (pfd.revents & POLLIN){
cmd = parse_cmd(state, cmd_file); cmd = parse_cmd(state, cmd_file);
if (cmd) { if (cmd) {
if (cmd < 0) D0(fprintf(debug_file, "Unrecognized command\n")); if (cmd < 0) D0(fprintf(debug_file, "Unrecognized command\n"));
...@@ -1674,6 +1713,7 @@ int listener_loop(camogm_state *state) ...@@ -1674,6 +1713,7 @@ int listener_loop(camogm_state *state)
state->rawdev.thread_state = STATE_RUNNING; state->rawdev.thread_state = STATE_RUNNING;
usleep(COMMAND_LOOP_DELAY); // make it longer but interruptible by signals? usleep(COMMAND_LOOP_DELAY); // make it longer but interruptible by signals?
} }
} // if pfd.revents & POLLIN
} // while (process) } // while (process)
// normally, we should not be here // normally, we should not be here
......
/** @brief This define is needed to use lseek64 and should be set before includes */
#define _LARGEFILE64_SOURCE
/** Needed for O_DIRECT */
#define _GNU_SOURCE
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <stdbool.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <linux/fs.h>
#include <ctype.h>
#include <sys/uio.h>
#include <poll.h>
// set to 1 second
#define CAMOGM_TIMEOUT 1000
int main(int argc, char *argv[]){
int f_ok;
int ret;
int fer, feo;
long int ftl;
int i=0;
const char pipe_name[] = "/tmp/fifo_test";
int flags;
char cmdbuf[1024];
int fl;
int somecounter = 0;
int writecounter = 0;
FILE *cmd_file;
struct pollfd pfd;
pfd.events = POLLIN;
printf("This is reader. It creates FIFO: %s\n",pipe_name);
// always delete pipe if it exists
f_ok = access(pipe_name, F_OK);
ret = unlink(pipe_name);
if (ret && f_ok == 0) {
printf("Some error\n");
}
ret = mkfifo(pipe_name, 0666); //EEXIST
if (ret) {
if (errno==EEXIST){
printf("Pipe exists\n");
}
}
cmd_file = open(pipe_name, O_RDWR|O_NONBLOCK);
pfd.fd = cmd_file;
fcntl(cmd_file, F_SETFL, 0); /* disable O_NONBLOCK */
printf("Pipe is now open for reading\n");
while(true){
ret = poll(&pfd, 1, CAMOGM_TIMEOUT); /* poll to avoid reading EOF */
somecounter +=1;
if (ret==0) {
printf("TIMEOUT %d\n",somecounter);
}
if (pfd.revents & POLLIN){
printf("PostPoll %d %d, revents = %d, errno = %d\n",somecounter,ret,pfd.revents,errno);
fl = read(cmd_file, cmdbuf, sizeof(cmdbuf));
//clearerr(cmd_file);
if (fl>0) {
writecounter +=1;
}
if (fl<0) {
printf("Error?\n");
break;
}
//fl = read(cmd_file,cmdbuf,sizeof(cmdbuf));
if ((fl>10)||(somecounter>10000000)) {
break;
}
}
}
printf("EXIT! errno=%d writes=%d wdc=%d\n",errno,writecounter,somecounter);
return 0;
}
/** @brief This define is needed to use lseek64 and should be set before includes */
#define _LARGEFILE64_SOURCE
/** Needed for O_DIRECT */
#define _GNU_SOURCE
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <stdbool.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <linux/fs.h>
#include <ctype.h>
#include <sys/uio.h>
int main(int argc, char *argv[]){
FILE *cmd_file;
const char pipe_name[] = "/tmp/fifo_test";
const char message[] = "test";
int ret;
printf("This is writer\n");
cmd_file = fopen(pipe_name, "w");
while(true){
ret = fwrite(message,sizeof(char),sizeof(message),cmd_file);
printf("Wrote %d bytes, fwrite returned %d\n",sizeof(message),ret);
}
return 0;
}
...@@ -1017,8 +1017,8 @@ void *reader(void *arg) ...@@ -1017,8 +1017,8 @@ void *reader(void *arg)
.sockfd_const = &sockfd, .sockfd_const = &sockfd,
.sockfd_temp = &fd .sockfd_temp = &fd
}; };
memset(&index_dir, 0, sizeof(struct disk_index)); memset(&index_dir, 0, sizeof(struct disk_idir));
memset(&index_sparse, 0, sizeof(struct disk_index)); memset(&index_sparse, 0, sizeof(struct disk_idir));
prep_socket(&sockfd, state->sock_port); prep_socket(&sockfd, state->sock_port);
pthread_cleanup_push(exit_thread, &exit_state); pthread_cleanup_push(exit_thread, &exit_state);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment