From 9948e538b58de1d523066cee4f560d7cfba46c30 Mon Sep 17 00:00:00 2001 From: gombasg Date: Fri, 7 Jul 2006 14:04:39 +0000 Subject: [PATCH] Ignore generated files Remove the checkpoint from the client - it is not the goal of this example Fix the XML descriptions Add a header for definitions common to the client and the master Make the master periodically send messages until the result is received git-svn-id: svn+ssh://cvs.lpds.sztaki.hu/var/lib/svn/szdg/dcapi/trunk@804 a7169a2c-3604-0410-bc95-c702d8d87f7a --- dcapi/examples/message-example/Makefile.am | 4 +- dcapi/examples/message-example/client.c | 165 +++++------------- dcapi/examples/message-example/common.h | 12 ++ dcapi/examples/message-example/master.c | 56 +++--- .../message-example-client.xml.in | 11 +- .../message-example-master.xml.in | 8 +- 6 files changed, 85 insertions(+), 171 deletions(-) create mode 100644 dcapi/examples/message-example/common.h diff --git a/dcapi/examples/message-example/Makefile.am b/dcapi/examples/message-example/Makefile.am index 5693692280..c2b570f8f5 100644 --- a/dcapi/examples/message-example/Makefile.am +++ b/dcapi/examples/message-example/Makefile.am @@ -18,11 +18,11 @@ endif CLEANFILES = message-example-client.xml message-example-master.xml -message_example_client_SOURCES = client.c +message_example_client_SOURCES = client.c common.h message_example_client_CPPFLAGS = $(DCAPI_CLIENT_CFLAGS) message_example_client_LDADD = $(DCAPI_CLIENT_LIBS) -message_example_master_SOURCES = master.c +message_example_master_SOURCES = master.c common.h message_example_master_CPPFLAGS = $(DCAPI_MASTER_CFLAGS) message_example_master_LDADD = $(DCAPI_MASTER_LIBS) diff --git a/dcapi/examples/message-example/client.c b/dcapi/examples/message-example/client.c index cffccec680..f97df846c3 100644 --- a/dcapi/examples/message-example/client.c +++ b/dcapi/examples/message-example/client.c @@ -1,3 +1,7 @@ +#ifdef HAVE_CONFIG_H +#include +#endif + #include #include @@ -5,80 +9,27 @@ #include #include -/* The logical file names, used at sequencial application */ -#define INPUT_NAME "in.txt" -#define OUTPUT_NAME "out.txt" +#include "common.h" static FILE *infile; static FILE *outfile; -/* Needed to report the percentage of the work already done */ -static int frac_total_size; -static int frac_current_pos; - -static int message_has_arrived = 0; - -/* Save the value of frac_current_pos to the ckpt file */ -static void do_checkpoint(void) -{ - char *ckptfile_name; - FILE *ckptfile; - int retval; - - /* Ensure that the output file is really on the disk before we create - * the checkpoint file */ - retval = fflush(outfile); - if (retval) - { - perror("APP: flushing the output file has failed"); - DC_finishClient(1); - } - - ckptfile_name = DC_resolveFileName(DC_FILE_OUT, DC_CHECKPOINT_FILE); - if (!ckptfile_name) - { - fprintf(stderr, "APP: Could not resolve the checkpoint file " - "name\n"); - DC_finishClient(1); - } - - ckptfile = fopen(ckptfile_name, "w"); - if (!ckptfile) - { - perror("APP: Could not create the checkpoint file"); - DC_finishClient(1); - } - - fprintf(ckptfile, "%d", frac_current_pos); - retval = fclose(ckptfile); - if (retval) - { - perror("APP: Closing the checkpoint file has failed"); - DC_finishClient(1); - } - - /* Tell the DC-API that the checkpoint is ready */ - DC_checkpointMade(ckptfile_name); - - /* Update the estimation about the work done */ - DC_fractionDone(frac_current_pos/frac_total_size); -} +static int messages_received; /* Open input and output files, and check is there is a checkpoint file */ static void init_files(void) { - const char *outfile_openmode = "w"; char *file_name; /* Open the input file */ - file_name = DC_resolveFileName(DC_FILE_IN, INPUT_NAME); + file_name = DC_resolveFileName(DC_FILE_IN, INPUT_LABEL); if (!file_name) { fprintf(stderr, "APP: Could not resolve the input file name\n"); DC_finishClient(1); } - infile = fopen(file_name, "rb"); + infile = fopen(file_name, "r"); if (!infile) { perror("APP: Could not open the input file"); @@ -86,80 +37,38 @@ static void init_files(void) } free(file_name); - /* Determine the size of the input file */ - fseek(infile, 0, SEEK_END); - frac_total_size = ftell(infile); - fseek(infile, 0, SEEK_SET); - - /* Check the checkpoint file */ - file_name = DC_resolveFileName(DC_FILE_IN, DC_CHECKPOINT_FILE); - if (file_name) - { - FILE *ckptfile; - int ret; - - ckptfile = fopen(file_name, "r"); - if (!ckptfile) - { - perror("APP: Could not open the initial checkpoint file"); - DC_finishClient(1); - } - free(file_name); - - /* ckpt file exists: read and set everything according to it */ - ret = fscanf(ckptfile, "%d", &frac_current_pos); - if (ret != 1 || frac_current_pos < 0 || - frac_current_pos > frac_total_size) - { - fprintf(stderr, "APP: Failed to parse the contents of " - "the checkpoint file, starting from the " - "beginning\n"); - frac_current_pos = 0; - } - else - { - fprintf(stderr, "APP: Found checkpoint file, starting " - "from position %d.\n", frac_current_pos); - outfile_openmode = "r+"; - } - fclose(ckptfile); - - fseek(infile, frac_current_pos, SEEK_SET); - } - /* Open the output file */ - file_name = DC_resolveFileName(DC_FILE_OUT, OUTPUT_NAME); + file_name = DC_resolveFileName(DC_FILE_OUT, OUTPUT_LABEL); if (!file_name) { fprintf(stderr, "APP: Could not resolve the output file name\n"); DC_finishClient(1); } - outfile = fopen(file_name, outfile_openmode); + outfile = fopen(file_name, "w"); if (!outfile) { perror("APP: Could not open/create the output file"); DC_finishClient(1); } free(file_name); - - /* If we are starting from a checkpoint file, restore the state of - * the output file as well */ - ftruncate(fileno(outfile), frac_current_pos); - fseek(outfile, 0, SEEK_END); } -static void message_arrived(char *message) +static void message_arrived(const char *message) { - fprintf(stderr, "APP: message: '%s' arrived\n", message); - DC_sendMessage("This is a sample reply message"); - fprintf(stderr, "APP: message: 'This is a sample reply message' sent\n"); - message_has_arrived = 1; + char reply[256]; + + fprintf(stderr, "APP: message: '%s' arrived, sending reply\n", message); + + snprintf(reply, sizeof(reply), "Reply to: %s", message); + DC_sendMessage(reply); + messages_received++; } /* The real work */ static void do_work(void) { + char buf[32]; int c; while ((c = fgetc(infile)) != EOF) @@ -172,11 +81,16 @@ static void do_work(void) perror("APP: fputc"); DC_finishClient(1); } - frac_current_pos++; + + /* Send the just-converted character to the master. This in + * turn also allows receiving messages from the master */ + snprintf(buf, sizeof(buf), "Processed %c", c); + DC_sendMessage(buf); /* Real applications do real computation that takes time. Here - * we just emulate it */ - sleep(5); + * we just emulate it. We sleep for a long time to prevent + * sending messages too often. */ + sleep(30); /* Check if either the master or the BOINC core client asked * us to do something */ @@ -184,11 +98,12 @@ static void do_work(void) if (!event) continue; - /* If it is time, do a checkpoint */ if (event->type == DC_CLIENT_CHECKPOINT) - do_checkpoint(); - - if (event->type == DC_CLIENT_MESSAGE) + { + DC_log(LOG_INFO, "Checkpoint request received"); + DC_checkpointMade(NULL); + } + else if (event->type == DC_CLIENT_MESSAGE) message_arrived(event->message); /* Make sure we do not leak memory */ @@ -213,14 +128,14 @@ int main(int argc, char *argv[]) "value was %d\n", retval); DC_finishClient(1); } - fprintf(stderr, "APP: DC-API initialization was successful.\n"); + fprintf(stdout, "APP: DC-API initialization was successful.\n"); init_files(); - do_work(); - fprintf(stderr, "APP: Work finished.\n"); - if (!message_has_arrived) - fprintf(stderr, "APP: Hasn't receaved any message from the master !!!\n"); + do_work(); + + fprintf(stdout, "APP: Work finished. Received %d messages from the " + "master.\n", messages_received); DC_finishClient(0); return(0); // Tho' we never reach this line @@ -230,13 +145,11 @@ int main(int argc, char *argv[]) int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR Args, int WinMode) { LPSTR command_line; - char* argv[100]; + char *argv[100]; int argc; command_line = GetCommandLine(); - argc = parse_command_line( command_line, argv ); + argc = parse_command_line(command_line, argv); return main(argc, argv); } #endif - - diff --git a/dcapi/examples/message-example/common.h b/dcapi/examples/message-example/common.h new file mode 100644 index 0000000000..ee05c5dd5a --- /dev/null +++ b/dcapi/examples/message-example/common.h @@ -0,0 +1,12 @@ +/* + * Common definitions used by both the master and the client + */ + +#ifndef COMMON_H +#define COMMON_H + +/* Logical names of the input/output files */ +#define INPUT_LABEL "in.txt" +#define OUTPUT_LABEL "out.txt" + +#endif /* COMMON_H */ diff --git a/dcapi/examples/message-example/master.c b/dcapi/examples/message-example/master.c index 49a37e2c39..38a3297a7d 100644 --- a/dcapi/examples/message-example/master.c +++ b/dcapi/examples/message-example/master.c @@ -20,6 +20,10 @@ * *****************************************************/ +#ifdef HAVE_CONFIG_H +#include +#endif + #include #include @@ -29,13 +33,7 @@ #include #include -#define INPUT_LABEL "in.txt" -#define OUTPUT_LABEL "out.txt" - -/* Number of WUs we have created */ -static int created_wus; -/* Number of results we have received so far */ -static int processed_wus; +#include "common.h" /* Command line options */ static const struct option longopts[] = @@ -45,27 +43,22 @@ static const struct option longopts[] = { NULL } }; +static int do_exit; + static void process_result(DC_Workunit *wu, DC_Result *result) { char *tag; - /* Internal housekeeping of the number of results we have seen */ - processed_wus++; - /* Extract our own private identifier */ tag = DC_getWUTag(wu); - DC_log(LOG_NOTICE, "Work unit %s has completed", tag); /* We no longer need the work unit */ DC_destroyWU(wu); - free(tag); -} -static void process_subresult(DC_Workunit *wu, const char *logicalFileName, const char *path) -{ - /* There is no subresult in this example */ + /* This will cause the main loop to quit */ + do_exit = 1; } static void process_message(DC_Workunit *wu, const char *message) @@ -78,9 +71,8 @@ static void process_message(DC_Workunit *wu, const char *message) free(tag); } -static void create_work(void) +static DC_Workunit *create_work(void) { - char ch; DC_Workunit *wu; wu = DC_createWU("message-example", NULL, 0, "message-test"); @@ -108,12 +100,7 @@ static void create_work(void) exit(1); } - created_wus++; - - printf("Press ENTER, after this WU is downloaded by a BOINC client"); - ch = getchar(); - - DC_sendWUMessage(wu, "This is a test message"); + return wu; } static void print_help(const char *prog) __attribute__((noreturn)); @@ -136,6 +123,7 @@ static void print_help(const char *prog) int main(int argc, char *argv[]) { char *config_file = NULL; + DC_Workunit *wu; int c; while ((c = getopt_long(argc, argv, "ch", longopts, NULL)) != -1) @@ -174,17 +162,23 @@ int main(int argc, char *argv[]) exit(1); } - /* We need the result callback function only */ - DC_setMasterCb(process_result, process_subresult, process_message); + /* Set the callbacks for receiving messages & the result */ + DC_setMasterCb(process_result, NULL, process_message); - DC_log(LOG_NOTICE, "Master: Creating work unit"); - create_work(); + wu = create_work(); DC_log(LOG_NOTICE, "Master: Work unit has been created. Waiting " - "for result/message ...\n"); + "for result/message"); /* Wait for the work units to finish */ - while (processed_wus < created_wus) - DC_processMasterEvents(600); + while (!do_exit) + { + DC_processMasterEvents(60); + + /* The result processing destroys the WU, so make sure we + * only try to send a message if the WU is still alive */ + if (!do_exit) + DC_sendWUMessage(wu, "What's up?"); + } return 0; } diff --git a/dcapi/examples/message-example/message-example-client.xml.in b/dcapi/examples/message-example/message-example-client.xml.in index 4646e44b1a..f3119944b8 100644 --- a/dcapi/examples/message-example/message-example-client.xml.in +++ b/dcapi/examples/message-example/message-example-client.xml.in @@ -1,10 +1,10 @@ - uppercase-example + message-example - Uppercase Example Application with callback functions + Messaging example - uppercase-example-client - - - + message-example-client - diff --git a/dcapi/examples/message-example/message-example-master.xml.in b/dcapi/examples/message-example/message-example-master.xml.in index aebae46fac..9d1bdb1e3f 100644 --- a/dcapi/examples/message-example/message-example-master.xml.in +++ b/dcapi/examples/message-example/message-example-master.xml.in @@ -1,10 +1,10 @@ - uppercase-example + message-example @@ -17,7 +17,7 @@ - uppercase-example-master + message-example-master --config ${workdir}/dc-api.conf @@ -35,7 +35,7 @@ -d 3 -app - uppercase-example + message-example