Christian Grothoff schrieb am Freitag, den 28. Oktober um 15:01 Uhr:
> Well, that's technically not required. You can simply integrate your data-
> polling loop into the external select loop of MHD and in the response
> callbacks for data-aquisition return 0 (which will be interpreted as "no data
> available yet, try again in the next round of select"). Note that MHD will
> then NOT put the respective sockets into your write set, so you would not end
> up busy-waiting.
Hm, looks like I do not fully understand this suggestion :(
Attached is a modified version fo your fileserver_example_external_select.c
example.
I just added a (fake) data acquisition loop which is currently using a 4
second interval. But how can I synchronice the http output for the
http data requests via http (and only for these) now?
Sven
--
TCP/IP: telecommunication protocol for imbibing pilsners
(Man-page uubp(1C) on Debian/GNU Linux)
/me is giggls@ircnet, http://sven.gegg.us/ on the Web
#include <stdio.h>
#include <stdlib.h>
#include <linux/rtc.h>
#include <sys/ioctl.h>
#include <string.h>
#include <microhttpd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#define PAGE "<html><head><title>File not found</title></head><body>File not found</body></html>"
static ssize_t file_reader (void *cls, uint64_t pos, char *buf, size_t max) {
FILE *file = cls;
(void) fseek (file, pos, SEEK_SET);
return fread (buf, 1, max, file);
}
static void free_callback (void *cls) {
FILE *file = cls;
fclose (file);
}
static int ahc_echo (void *cls,
struct MHD_Connection *connection,
const char *url,
const char *method,
const char *version,
const char *upload_data,
size_t *upload_data_size, void **ptr) {
static int aptr;
struct MHD_Response *response;
int ret;
FILE *file;
struct stat buf;
if (0 != strcmp (method, MHD_HTTP_METHOD_GET))
return MHD_NO; /* unexpected method */
if (&aptr != *ptr)
{
/* do never respond on first call */
*ptr = &aptr;
return MHD_YES;
}
*ptr = NULL; /* reset when done */
if ( (0 == stat (&url[1], &buf)) &&
(S_ISREG (buf.st_mode)) )
file = fopen (&url[1], "rb");
else
file = NULL;
if (file == NULL)
{
response = MHD_create_response_from_buffer (strlen (PAGE),
(void *) PAGE,
MHD_RESPMEM_PERSISTENT);
ret = MHD_queue_response (connection, MHD_HTTP_NOT_FOUND, response);
MHD_destroy_response (response);
}
else
{
response = MHD_create_response_from_callback (buf.st_size, 32 * 1024, /* 32k page size */
&file_reader,
file,
&free_callback);
if (response == NULL)
{
fclose (file);
return MHD_NO;
}
ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
MHD_destroy_response (response);
}
return ret;
}
int main () {
struct MHD_Daemon *d;
fd_set rs;
fd_set ws;
fd_set es;
int max,rtcfd;
unsigned long data;
int tirq,acqdelay=4;
d = MHD_start_daemon (MHD_USE_DEBUG,
8888,
NULL, NULL, &ahc_echo, PAGE, MHD_OPTION_END);
if (d == NULL)
return 1;
rtcfd = open("/dev/rtc0", O_RDONLY);
if (rtcfd == -1) {
fprintf(stderr,"error opening /dev/rtc0");
exit(EXIT_FAILURE);
}
/* Turn on update interrupts (one per second) */
ioctl(rtcfd, RTC_UIE_ON, 0);
tirq=acqdelay-1;
while (1) {
max = 0;
FD_ZERO (&rs);
FD_ZERO (&ws);
FD_ZERO (&es);
if (MHD_YES != MHD_get_fdset (d, &rs, &ws, &es, &max))
break; /* fatal internal error */
FD_SET(rtcfd,&rs);
if (rtcfd >max) max=rtcfd;
select (max + 1, &rs, &ws, &es, NULL);
if (FD_ISSET(rtcfd,&rs)) {
read(rtcfd, &data, sizeof(unsigned long));
tirq++;
if (tirq==acqdelay) {
printf("do data acq here\n");
tirq=0;
}
} else {
MHD_run (d);
}
}
MHD_stop_daemon (d);
return 0;
}