diff --git a/src/zmapServer/README b/src/zmapServer/README new file mode 100755 index 0000000000000000000000000000000000000000..2b1d9204be9e3ee1bf95ee46db76d1c810b67fae --- /dev/null +++ b/src/zmapServer/README @@ -0,0 +1,7 @@ +================================================================================ +Server interface + +Code that provides an interface to contacting a server over the network and +asking for and collecting data from the server. + +Subdirectories contain any code required for particular servers. diff --git a/src/zmapServer/makefile b/src/zmapServer/makefile new file mode 100755 index 0000000000000000000000000000000000000000..34c94e962f8a0c4288ceffc5ac4d20c734425f82 --- /dev/null +++ b/src/zmapServer/makefile @@ -0,0 +1,30 @@ +# +# Makes the manager part of the ZMap application. +# + + +# local macros +SERV_PRIV_HDRS = zmapServer_P.h +PUB_HDRS = zmapServer.h +SERV_SRC = zmapServer.c +SERV_OBJ = zmapServer.o + + + +# +# These must all be set for the common includes to work. +# Need to include AceConn header. +# +CURRENT_LIB = $(ZMAP_LIB) +CURRENT_OBJ = $(SERV_OBJ) +CURRENT_DEP = $(PUB_HDRS) $(SERV_PRIV_HDRS) +CURRENT_SRC = $(SERV_PRIV_HDRS) $(SERV_SRC) +CURRENT_INC = -I$(HOME)/acedb/CODE/Ace-Conn + +# +# point to common make include file which contains all the rules etc. +# +ROOT_DIRECTORY = .. +MAKE_DIR = $(ROOT_DIRECTORY)/zmapMake +include $(MAKE_DIR)/build.make + diff --git a/src/zmapServer/zmapServer.c b/src/zmapServer/zmapServer.c new file mode 100755 index 0000000000000000000000000000000000000000..3cdef3c9e45c15bfc54e10cace01275200b24339 --- /dev/null +++ b/src/zmapServer/zmapServer.c @@ -0,0 +1,132 @@ +/* File: zmapServer.c + * Author: Ed Griffiths (edgrif@sanger.ac.uk) + * Copyright (c) Sanger Institute, 2003 + *------------------------------------------------------------------- + * ZMap is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * or see the on-line version at http://www.gnu.org/copyleft/gpl.txt + *------------------------------------------------------------------- + * This file is part of the ZMap genome database package + * and was written by + * Ed Griffiths (Sanger Institute, UK) edgrif@sanger.ac.uk, + * Simon Kelley (Sanger Institute, UK) srk@sanger.ac.uk and + * Rob Clack (Sanger Institute, UK) rnc@sanger.ac.uk + * + * Description: + * Exported functions: See zmapServer.h + * HISTORY: + * Last edited: Sep 5 16:20 2003 (edgrif) + * Created: Wed Aug 6 15:46:38 2003 (edgrif) + * CVS info: $Id: zmapServer.c,v 1.1 2003-11-13 15:01:09 edgrif Exp $ + *------------------------------------------------------------------- + */ + +#include <AceConn.h> +#include <zmapServer_P.h> + + + +gboolean zMapServerCreateConnection(ZMapServer *server_out, char *host, int port, + char *userid, char *passwd) +{ + gboolean result = FALSE ; + ZMapServer server ; + AceConnection connection = NULL ; + AceConnStatus status ; + + /* slightly odd, always return a struct to provide error information. */ + server = g_new(ZMapServerStruct, sizeof(ZMapServerStruct)) ; /* n.b. crashes on failure. */ + *server_out = server ; + + if ((status = AceConnCreate(&connection, host, port, userid, passwd, 20)) == ACECONN_OK) + { + /* Don't know if we really need to keep hold of these... */ + server->host = g_strdup(host) ; + server->port = port ; + + server->connection = connection ; + + server->last_error_msg = NULL ; + + result = TRUE ; + } + else + server->last_error_msg = AceConnGetErrorMsg(connection, status) ; + + return result ; +} + + +gboolean zMapServerOpenConnection(ZMapServer server) +{ + gboolean result = FALSE ; + AceConnStatus status ; + + if ((status = AceConnConnect(server->connection)) == ACECONN_OK) + result = TRUE ; + else + server->last_error_msg = AceConnGetErrorMsg(server->connection, status) ; + + return result ; +} + + +gboolean zMapServerRequest(ZMapServer server, char *request, char **reply) +{ + gboolean result = FALSE ; + int reply_len = 0 ; + AceConnStatus status ; + + if ((status = AceConnRequest(server->connection, request, (void **)reply, &reply_len)) == ACECONN_OK) + result = TRUE ; + else + server->last_error_msg = AceConnGetErrorMsg(server->connection, status) ; + + return result ; +} + +gboolean zMapServerCloseConnection(ZMapServer server) +{ + gboolean result = TRUE ; + AceConnStatus status ; + + if ((status = AceConnConnectionOpen(server->connection)) == ACECONN_OK) + { + if ((status = AceConnDisconnect(server->connection)) != ACECONN_OK) + result = FALSE ; + else + server->last_error_msg = AceConnGetErrorMsg(server->connection, status) ; + } + else + server->last_error_msg = AceConnGetErrorMsg(server->connection, status) ; + + return result ; +} + +gboolean zMapServerFreeConnection(ZMapServer server) +{ + gboolean result = TRUE ; + + AceConnDestroy(server->connection) ; /* Does not fail. */ + g_free(server->host) ; + g_free(server) ; + + return result ; +} + + +char *zMapServerLastErrorMsg(ZMapServer server) +{ + return server->last_error_msg ; +} diff --git a/src/zmapServer/zmapServer_P.h b/src/zmapServer/zmapServer_P.h new file mode 100755 index 0000000000000000000000000000000000000000..1bde57e10f9822066abc0239a3421e87acbc2cc1 --- /dev/null +++ b/src/zmapServer/zmapServer_P.h @@ -0,0 +1,57 @@ +/* File: zmapServer_P.h + * Author: Ed Griffiths (edgrif@sanger.ac.uk) + * Copyright (c) Sanger Institute, 2003 + *------------------------------------------------------------------- + * ZMap is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * or see the on-line version at http://www.gnu.org/copyleft/gpl.txt + *------------------------------------------------------------------- + * This file is part of the ZMap genome database package + * and was written by + * Ed Griffiths (Sanger Institute, UK) edgrif@sanger.ac.uk, + * Simon Kelley (Sanger Institute, UK) srk@sanger.ac.uk and + * Rob Clack (Sanger Institute, UK) rnc@sanger.ac.uk + * + * Description: + * Exported functions: See XXXXXXXXXXXXX.h + * HISTORY: + * Last edited: Nov 12 15:59 2003 (edgrif) + * Created: Wed Aug 6 15:48:47 2003 (edgrif) + * CVS info: $Id: zmapServer_P.h,v 1.1 2003-11-13 15:01:09 edgrif Exp $ + *------------------------------------------------------------------- + */ +#ifndef ZMAP_SERVER_P_H +#define ZMAP_SERVER_P_H + +#include <ZMap/zmapServer.h> + + +/* A connection to a database. */ +typedef struct _ZMapServerStruct +{ + char *host ; + int port ; + + AceConnection connection ; + + char *last_error_msg ; + +} ZMapServerStruct ; + + + + + + +#endif /* !ZMAP_SERVER_P_H */ diff --git a/src/zmapThreads/README b/src/zmapThreads/README new file mode 100755 index 0000000000000000000000000000000000000000..5b0566958c13662e520c2d8db779ee74bd954492 --- /dev/null +++ b/src/zmapThreads/README @@ -0,0 +1,5 @@ +================================================================================ +threads + +Code to create and run threads and have them interact with the main zmapwindow +code. diff --git a/src/zmapThreads/makefile b/src/zmapThreads/makefile new file mode 100755 index 0000000000000000000000000000000000000000..adf5118330e8a09ec8a1963572929297cc68c429 --- /dev/null +++ b/src/zmapThreads/makefile @@ -0,0 +1,28 @@ +# +# Makes the manager part of the ZMap application. +# + + +# local macros +PUB_HDRS = zmapSys.h zmapConn.h zmapServer.h +APP_PRIV_HDRS = zmapConn_P.h zmapSlave_P.h +APP_SRC = zmapConn.c zmapSlave.c zmapConnutils.c +APP_OBJ = zmapConn.o zmapSlave.o zmapConnutils.o + +# the main routines will need some different treatment maybe...???? try putting +# them all together, don't know if it will work..... + +# +# These must all be set for the common includes to work. +# +CURRENT_LIB = $(ZMAP_LIB) +CURRENT_OBJ = $(APP_OBJ) +CURRENT_DEP = $(PUB_HDRS) $(APP_PRIV_HDRS) +CURRENT_SRC = $(APP_PRIV_HDRS) $(APP_SRC) + +# +# point to common make include file which contains all the rules etc. +# +ROOT_DIRECTORY = .. +MAKE_DIR = $(ROOT_DIRECTORY)/zmapMake +include $(MAKE_DIR)/build.make diff --git a/src/zmapThreads/zmapConn.c b/src/zmapThreads/zmapConn.c new file mode 100755 index 0000000000000000000000000000000000000000..bef8e0df63b9def81e7803d2687d42c971cee8ef --- /dev/null +++ b/src/zmapThreads/zmapConn.c @@ -0,0 +1,183 @@ +/* File: zmapthrcontrol.c + * Author: Ed Griffiths (edgrif@sanger.ac.uk) + * Copyright (c) Sanger Institute, 2003 + *------------------------------------------------------------------- + * ZMap is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * or see the on-line version at http://www.gnu.org/copyleft/gpl.txt + *------------------------------------------------------------------- + * This file is part of the ZMap genome database package + * and was written by + * Rob Clack (Sanger Institute, UK) rnc@sanger.ac.uk, + * Ed Griffiths (Sanger Institute, UK) edgrif@sanger.ac.uk and + * Simon Kelley (Sanger Institute, UK) srk@sanger.ac.uk + * + * Description: + * Exported functions: See XXXXXXXXXXXXX.h + * HISTORY: + * Last edited: Sep 3 16:25 2003 (edgrif) + * Created: Thu Jul 24 14:37:18 2003 (edgrif) + * CVS info: $Id: zmapConn.c,v 1.1 2003-11-13 15:02:12 edgrif Exp $ + *------------------------------------------------------------------- + */ + +#include <zmapConn_P.h> + +/* Turn on/off all debugging messages for threads. */ +gboolean zmap_thr_debug_G = TRUE ; + + + + + +ZMapConnection zMapConnCreate(char *machine, int port, char *sequence) +{ + ZMapConnection connection ; + pthread_t thread_id ; + pthread_attr_t thread_attr ; + int status ; + + connection = g_new(ZMapConnectionStruct, sizeof(ZMapConnectionStruct)) ; + + connection->machine = g_strdup(machine) ; + connection->port = port ; + connection->sequence = g_strdup(sequence) ; + + /* ok to just set state here because we have not started the thread yet.... */ + zmapCondVarCreate(&(connection->request)) ; + connection->request.state = ZMAP_REQUEST_WAIT ; + + zmapVarCreate(&(connection->reply)) ; + connection->reply.state = ZMAP_REPLY_WAIT ; + + + /* Set the new threads attributes so it will run "detached", we do not want anything from them. + * when they die, we want them to go away and release their resources. */ + if ((status = pthread_attr_init(&thread_attr)) != 0) + { + ZMAPSYSERR(status, "Create thread attibutes") ; + } + + if ((status = pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED)) != 0) + { + ZMAPSYSERR(status, "Set thread detached attibute") ; + } + + + /* Create the new thread. */ + if ((status = pthread_create(&thread_id, &thread_attr, zmapNewThread, (void *)connection)) != 0) + { + ZMAPSYSERR(status, "Thread creation") ; + } + + + connection->thread_id = thread_id ; + + + return connection ; +} + + +void zMapConnLoadData(ZMapConnection connection) +{ + zmapCondVarSignal(&connection->request, ZMAP_REQUEST_GETDATA) ; + + return ; +} + + +gboolean zMapConnGetReply(ZMapConnection connection, ZMapThreadReply *state) +{ + gboolean got_value ; + + got_value = zmapVarGetValue(&(connection->reply), state) ; + + return got_value ; +} + + + +void zMapConnSetReply(ZMapConnection connection, ZMapThreadReply state) +{ + zmapVarSetValue(&(connection->reply), state) ; + + return ; +} + + +gboolean zMapConnGetReplyWithData(ZMapConnection connection, ZMapThreadReply *state, + void **data, char **err_msg) +{ + gboolean got_value ; + + got_value = zmapVarGetValueWithData(&(connection->reply), state, data, err_msg) ; + + return got_value ; +} + + + + + +pthread_t zMapConnGetThreadid(ZMapConnection connection) +{ + return connection->thread_id ; +} + +/* Kill the thread by cancelling it, as this will asynchronously we cannot release the connections + * resources in this call. */ +void zMapConnKill(ZMapConnection connection) +{ + int status ; + + ZMAP_THR_DEBUG(("GUI: killing and destroying connection for thread %x\n", connection->thread_id)) ; + + /* Really we should signal an exit here...but that lead to deadlocks, think about this bit.. */ + + /* Signal the thread to cancel it, we could set a cond var of EXIT but this will take ages + * for the thread to be cancelled. */ + if ((status = pthread_cancel(connection->thread_id)) != 0) + { + ZMAPSYSERR(status, "Thread cancel") ; + } + + return ; +} + + +/* Release the connections resources, don't do this until the slave thread has gone. */ +void zMapConnDestroy(ZMapConnection connection) +{ + int status ; + + ZMAP_THR_DEBUG(("GUI: destroying connection for thread %x\n", connection->thread_id)) ; + + zmapVarDestroy(&connection->reply) ; + zmapCondVarDestroy(&(connection->request)) ; + + g_free(connection->machine) ; + g_free(connection->sequence) ; + + g_free(connection) ; + + return ; +} + + + + +/* + * --------------------- Internal routines ------------------------------ + */ + diff --git a/src/zmapThreads/zmapConn_P.h b/src/zmapThreads/zmapConn_P.h new file mode 100755 index 0000000000000000000000000000000000000000..749d9969efe616236335edf6a293d751af0eb5e5 --- /dev/null +++ b/src/zmapThreads/zmapConn_P.h @@ -0,0 +1,126 @@ +/* File: zmapConn_P.h + * Author: Ed Griffiths (edgrif@sanger.ac.uk) + * Copyright (c) Sanger Institute, 2003 + *------------------------------------------------------------------- + * ZMap is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * or see the on-line version at http://www.gnu.org/copyleft/gpl.txt + *------------------------------------------------------------------- + * This file is part of the ZMap genome database package + * and was written by + * Rob Clack (Sanger Institute, UK) rnc@sanger.ac.uk, + * Ed Griffiths (Sanger Institute, UK) edgrif@sanger.ac.uk and + * Simon Kelley (Sanger Institute, UK) srk@sanger.ac.uk + * + * Description: + * Exported functions: See XXXXXXXXXXXXX.h + * HISTORY: + * Last edited: Nov 12 16:35 2003 (edgrif) + * Created: Thu Jul 24 14:36:08 2003 (edgrif) + * CVS info: $Id: zmapConn_P.h,v 1.1 2003-11-13 15:02:12 edgrif Exp $ + *------------------------------------------------------------------- + */ +#ifndef ZMAP_CONN_PRIV_H +#define ZMAP_CONN_PRIV_H + + +#include <pthread.h> +#include <glib.h> +#include <ZMap/zmapSys.h> +#include <ZMap/zmapConn.h> + + +/* Seems that Linux defines the time structure used in some pthread calls as "timespec", + * whereas alphas call it "timespec_t"....deep sigh.... */ +#ifdef LINUX +#define TIMESPEC struct timespec +#else +#define TIMESPEC timespec_t +#endif + +#define ZMAP_THR_DEBUG(ALL_ARGS_WITH_BRACKETS) \ +do { \ + if (zmap_thr_debug_G) \ + printf ALL_ARGS_WITH_BRACKETS ; \ + } while (0) + + +/* Requests are via a cond var system. */ +typedef struct +{ + pthread_mutex_t mutex ; /* controls access to this struct. */ + pthread_cond_t cond ; /* Slave waits on this. */ + ZMapThreadRequest state ; /* Contains request to slave. */ +} ZMapRequestStruct, *ZMapRequest ; + +/* Replies via a simpler mutex. */ +typedef struct +{ + pthread_mutex_t mutex ; /* controls access to this struct. */ + ZMapThreadReply state ; /* Contains reply from slave. */ + char *data ; /* May also contain data for some replies. */ + char *error_msg ; /* May contain error message for when + thread fails. */ +} ZMapReplyStruct, *ZMapReply ; + + + +/* The ZMapConnection, there is one per connection to a database, i.e. one per slave + * thread. */ +typedef struct _ZMapConnectionStruct +{ + /* These are read only after creation of the thread. */ + gchar *machine ; + int port ; + gchar *sequence ; + pthread_t thread_id ; + + + /* These control the communication between the GUI thread and the connection threads, + * they are mutex locked and the request code makes use of the condition variable. */ + ZMapRequestStruct request ; /* GUIs request. */ + ZMapReplyStruct reply ; /* Slaves reply. */ + +} ZMapConnectionStruct ; + + +/* Thread calls. */ +void *zmapNewThread(void *thread_args) ; + + +/* Request routines. */ +void zmapCondVarCreate(ZMapRequest thread_state) ; +void zmapCondVarSignal(ZMapRequest thread_state, ZMapThreadRequest new_state) ; +void zmapCondVarWait(ZMapRequest thread_state, ZMapThreadRequest waiting_state) ; +ZMapThreadRequest zmapCondVarWaitTimed(ZMapRequest condvar, ZMapThreadRequest waiting_state, + TIMESPEC *timeout, gboolean reset_to_waiting) ; +void zmapCondVarDestroy(ZMapRequest thread_state) ; + +char *zmapVarGetRequestString(ZMapThreadRequest signalled_state) ; + + + +/* Reply routines. */ +void zmapVarCreate(ZMapReply thread_state) ; +void zmapVarSetValue(ZMapReply thread_state, ZMapThreadReply new_state) ; +gboolean zmapVarGetValue(ZMapReply thread_state, ZMapThreadReply *state_out) ; +void zmapVarSetValueWithData(ZMapReply thread_state, ZMapThreadReply new_state, void *data) ; +void zmapVarSetValueWithError(ZMapReply thread_state, ZMapThreadReply new_state, char *err_msg) ; +gboolean zmapVarGetValueWithData(ZMapReply thread_state, ZMapThreadReply *state_out, + void **data_out, char **err_msg_out) ; +void zmapVarDestroy(ZMapReply thread_state) ; + +char *zmapVarGetReplyString(ZMapThreadReply signalled_state) ; + +#endif /* !ZMAP_CONN_PRIV_H */ diff --git a/src/zmapThreads/zmapConnutils.c b/src/zmapThreads/zmapConnutils.c new file mode 100755 index 0000000000000000000000000000000000000000..49cbf9f077a653ab25ceec3a7098ab7375bce863 --- /dev/null +++ b/src/zmapThreads/zmapConnutils.c @@ -0,0 +1,405 @@ +/* File: zmapthrutils.c + * Author: Ed Griffiths (edgrif@sanger.ac.uk) + * Copyright (c) Sanger Institute, 2003 + *------------------------------------------------------------------- + * ZMap is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * or see the on-line version at http://www.gnu.org/copyleft/gpl.txt + *------------------------------------------------------------------- + * This file is part of the ZMap genome database package + * and was written by + * Rob Clack (Sanger Institute, UK) rnc@sanger.ac.uk, + * Ed Griffiths (Sanger Institute, UK) edgrif@sanger.ac.uk and + * Simon Kelley (Sanger Institute, UK) srk@sanger.ac.uk + * + * Description: + * Exported functions: See XXXXXXXXXXXXX.h + * HISTORY: + * Last edited: Nov 12 16:42 2003 (edgrif) + * Created: Thu Jul 24 14:37:35 2003 (edgrif) + * CVS info: $Id: zmapConnutils.c,v 1.1 2003-11-13 15:02:13 edgrif Exp $ + *------------------------------------------------------------------- + */ + +#include <errno.h> +#include <zmapConn_P.h> + + +static void releaseCondvarMutex(void *thread_data) ; + + + + +void zmapCondVarCreate(ZMapRequest thread_state) +{ + int status ; + + if ((status = pthread_mutex_init(&(thread_state->mutex), NULL)) != 0) + { + ZMAPSYSERR(status, "mutex init") ; + } + + if ((status = pthread_cond_init(&(thread_state->cond), NULL)) != 0) + { + ZMAPSYSERR(status, "cond init") ; + } + + thread_state->state = ZMAP_REQUEST_INIT ; + + return ; +} + +void zmapCondVarSignal(ZMapRequest thread_state, ZMapThreadRequest new_state) +{ + int status ; + + pthread_cleanup_push(releaseCondvarMutex, (void *)thread_state) ; + + if ((status = pthread_mutex_lock(&(thread_state->mutex))) != 0) + { + ZMAPSYSERR(status, "zmapCondVarSignal mutex lock") ; + } + + thread_state->state = new_state ; + + if ((status = pthread_cond_signal(&(thread_state->cond))) != 0) + { + ZMAPSYSERR(status, "zmapCondVarSignal cond signal") ; + } + + if ((status = pthread_mutex_unlock(&(thread_state->mutex))) != 0) + { + ZMAPSYSERR(status, "zmapCondVarSignal mutex unlock") ; + } + + pthread_cleanup_pop(0) ; /* 0 => only call cleanup if cancelled. */ + + return ; +} + + +/* Blocking wait.... */ +void zmapCondVarWait(ZMapRequest thread_state, ZMapThreadRequest waiting_state) +{ + int status ; + + pthread_cleanup_push(releaseCondvarMutex, (void *)thread_state) ; + + if ((status = pthread_mutex_lock(&(thread_state->mutex))) != 0) + { + ZMAPSYSERR(status, "zmapCondVarWait mutex lock") ; + } + + while (thread_state->state == waiting_state) + { + if ((status = pthread_cond_wait(&(thread_state->cond), &(thread_state->mutex))) != 0) + { + ZMAPSYSERR(status, "zmapCondVarWait cond wait") ; + } + } + + if ((status = pthread_mutex_unlock(&(thread_state->mutex))) != 0) + { + ZMAPSYSERR(status, "zmapCondVarWait mutex unlock") ; + } + + pthread_cleanup_pop(0) ; /* 0 => only call cleanup if cancelled. */ + + return ; +} + + +/* timed wait, returns FALSE if cond var was not signalled (i.e. it timed out), + * TRUE otherwise.... + * NOTE that you can optionally get the condvar state reset to the waiting_state, this + * can be useful if you are calling this routine from a loop in which you wait until + * something has changed from the waiting state...i.e. somehow you need to return to the + * waiting state before looping again. */ +ZMapThreadRequest zmapCondVarWaitTimed(ZMapRequest condvar, ZMapThreadRequest waiting_state, + TIMESPEC *relative_timeout, gboolean reset_to_waiting) +{ + ZMapThreadRequest signalled_state = ZMAP_REQUEST_INIT ; + int status ; + TIMESPEC systimeout ; + + + pthread_cleanup_push(releaseCondvarMutex, (void *)condvar) ; + + + if ((status = pthread_mutex_lock(&(condvar->mutex))) != 0) + { + ZMAPSYSERR(status, "zmapCondVarWait mutex lock") ; + } + + /* Get the relative timeout converted to absolute for the call. */ + if ((status = pthread_get_expiration_np(relative_timeout, &systimeout)) != 0) + ZMAPSYSERR(status, "zmapCondVarWaitTimed invalid time") ; + + while (condvar->state == waiting_state) + { + if ((status = pthread_cond_timedwait(&(condvar->cond), &(condvar->mutex), + &systimeout)) != 0) + { + if (status == ETIMEDOUT) /* Timed out so return. */ + { + condvar->state = ZMAP_REQUEST_TIMED_OUT ; + break ; + } + else + ZMAPSYSERR(status, "zmapCondVarWait cond wait") ; + } + } + + signalled_state = condvar->state ; /* return signalled end state. */ + + /* optionally reset current state to wait state. */ + if (reset_to_waiting) + condvar->state = waiting_state ; + + if ((status = pthread_mutex_unlock(&(condvar->mutex))) != 0) + { + ZMAPSYSERR(status, "zmapCondVarWait mutex unlock") ; + } + + pthread_cleanup_pop(0) ; /* 0 => only call cleanup if cancelled. */ + + return signalled_state ; +} + + +void zmapCondVarDestroy(ZMapRequest thread_state) +{ + int status ; + + if ((status = pthread_cond_destroy(&(thread_state->cond))) != 0) + { + ZMAPSYSERR(status, "cond destroy") ; + } + + + if ((status = pthread_mutex_destroy(&(thread_state->mutex))) != 0) + { + ZMAPSYSERR(status, "mutex destroy") ; + } + + return ; +} + + +/* Must be kept in step with declaration of ZMapThreadRequest enums in zmapConn_P.h */ +char *zmapVarGetRequestString(ZMapThreadRequest signalled_state) +{ + char *str_states[] = {"ZMAP_REQUEST_INIT", "ZMAP_REQUEST_WAIT", "ZMAP_REQUEST_TIMED_OUT", + "ZMAP_REQUEST_GETDATA", "ZMAP_REQUEST_EXIT"} ; + + return str_states[signalled_state] ; +} + + + + +/* this set of routines manipulates the variable in the thread state struct but do not + * involve the Condition Variable. */ + +void zmapVarCreate(ZMapReply thread_state) +{ + int status ; + + if ((status = pthread_mutex_init(&(thread_state->mutex), NULL)) != 0) + { + ZMAPSYSERR(status, "mutex init") ; + } + + thread_state->state = ZMAP_REPLY_INIT ; + + return ; +} + + + +void zmapVarSetValue(ZMapReply thread_state, ZMapThreadReply new_state) +{ + int status ; + + if ((status = pthread_mutex_lock(&(thread_state->mutex))) != 0) + { + ZMAPSYSERR(status, "zmapVarSetValue mutex lock") ; + } + + thread_state->state = new_state ; + + if ((status = pthread_mutex_unlock(&(thread_state->mutex))) != 0) + { + ZMAPSYSERR(status, "zmapVarSetValue mutex unlock") ; + } + + return ; +} + + +/* Returns TRUE if it could read the value (i.e. the mutex was unlocked) + * and returns the value in state_out, + * returns FALSE otherwise. */ +gboolean zmapVarGetValue(ZMapReply thread_state, ZMapThreadReply *state_out) +{ + gboolean unlocked = TRUE ; + int status ; + + if ((status = pthread_mutex_trylock(&(thread_state->mutex))) != 0) + { + if (status == EBUSY) + unlocked = FALSE ; + else + ZMAPSYSERR(status, "zmapVarGetValue mutex lock") ; + } + else + { + *state_out = thread_state->state ; + unlocked = TRUE ; + + if ((status = pthread_mutex_unlock(&(thread_state->mutex))) != 0) + { + ZMAPSYSERR(status, "zmapVarGetValue mutex unlock") ; + } + } + + return unlocked ; +} + + +void zmapVarSetValueWithData(ZMapReply thread_state, ZMapThreadReply new_state, void *data) +{ + int status ; + + if ((status = pthread_mutex_lock(&(thread_state->mutex))) != 0) + { + ZMAPSYSERR(status, "zmapVarSetValueWithData mutex lock") ; + } + + thread_state->state = new_state ; + thread_state->data = data ; + + if ((status = pthread_mutex_unlock(&(thread_state->mutex))) != 0) + { + ZMAPSYSERR(status, "zmapVarSetValueWithData mutex unlock") ; + } + + return ; +} + + +void zmapVarSetValueWithError(ZMapReply thread_state, ZMapThreadReply new_state, char *err_msg) +{ + int status ; + + if ((status = pthread_mutex_lock(&(thread_state->mutex))) != 0) + { + ZMAPSYSERR(status, "zmapVarSetValueWithError mutex lock") ; + } + + thread_state->state = new_state ; + thread_state->error_msg = err_msg ; + + if ((status = pthread_mutex_unlock(&(thread_state->mutex))) != 0) + { + ZMAPSYSERR(status, "zmapVarSetValueWithError mutex unlock") ; + } + + return ; +} + + +/* Returns TRUE if it could read the value (i.e. the mutex was unlocked) + * and returns the value in state_out and also if there is any data it + * is returned in data_out and if there is an err_msg it is returned in err_msg_out, + * returns FALSE if it could not read the value. */ +gboolean zmapVarGetValueWithData(ZMapReply thread_state, ZMapThreadReply *state_out, + void **data_out, char **err_msg_out) +{ + gboolean unlocked = TRUE ; + int status ; + + if ((status = pthread_mutex_trylock(&(thread_state->mutex))) != 0) + { + if (status == EBUSY) + unlocked = FALSE ; + else + ZMAPSYSERR(status, "zmapVarGetValue mutex lock") ; + } + else + { + *state_out = thread_state->state ; + if (thread_state->data) + *data_out = thread_state->data ; + if (thread_state->error_msg) + *err_msg_out = thread_state->error_msg ; + + unlocked = TRUE ; + + if ((status = pthread_mutex_unlock(&(thread_state->mutex))) != 0) + { + ZMAPSYSERR(status, "zmapVarGetValue mutex unlock") ; + } + } + + return unlocked ; +} + + +void zmapVarDestroy(ZMapReply thread_state) +{ + int status ; + + if ((status = pthread_mutex_destroy(&(thread_state->mutex))) != 0) + { + ZMAPSYSERR(status, "mutex destroy") ; + } + + return ; +} + + + +/* Must be kept in step with declaration of ZMapThreadReply enums in zmapConn_P.h */ +char *zmapVarGetReplyString(ZMapThreadReply signalled_state) +{ + char *str_states[] = {"ZMAP_REPLY_INIT", "ZMAP_REPLY_WAIT", + "ZMAP_REPLY_GOTDATA", "ZMAP_REPLY_EXIT", "ZMAP_REPLY_DESTROYED"} ; + + return str_states[signalled_state] ; +} + + + + +/* + * ----------------------- Internal Routines ----------------------- + */ + +/* Called when a thread gets cancelled while waiting on a mutex to ensure that the mutex + * gets released. */ +static void releaseCondvarMutex(void *thread_data) +{ + ZMapRequest condvar = (ZMapRequest)thread_data ; + int status ; + + ZMAP_THR_DEBUG(("releaseCondvarMutex cleanup handler\n")) ; + + if ((status = pthread_mutex_unlock(&(condvar->mutex))) != 0) + { + ZMAPSYSERR(status, "releaseCondvarMutex cleanup handler - mutex unlock") ; + } + + return ; +} diff --git a/src/zmapThreads/zmapSlave.c b/src/zmapThreads/zmapSlave.c new file mode 100755 index 0000000000000000000000000000000000000000..24f0c1746ce1a0b62c236ee966f4e42588c50def --- /dev/null +++ b/src/zmapThreads/zmapSlave.c @@ -0,0 +1,234 @@ +/* File: zmapthrslave.c + * Author: Ed Griffiths (edgrif@sanger.ac.uk) + * Copyright (c) Sanger Institute, 2003 + *------------------------------------------------------------------- + * ZMap is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * or see the on-line version at http://www.gnu.org/copyleft/gpl.txt + *------------------------------------------------------------------- + * This file is part of the ZMap genome database package + * and was written by + * Rob Clack (Sanger Institute, UK) rnc@sanger.ac.uk, + * Ed Griffiths (Sanger Institute, UK) edgrif@sanger.ac.uk and + * Simon Kelley (Sanger Institute, UK) srk@sanger.ac.uk + * + * Description: + * Exported functions: See XXXXXXXXXXXXX.h + * HISTORY: + * Last edited: Nov 12 16:36 2003 (edgrif) + * Created: Thu Jul 24 14:37:26 2003 (edgrif) + * CVS info: $Id: zmapSlave.c,v 1.1 2003-11-13 15:02:13 edgrif Exp $ + *------------------------------------------------------------------- + */ + +/* With some additional calls in the zmapConn code I could get rid of the need for + * the private header here...... */ + +#include <zmapConn_P.h> +#include <ZMap/zmapServer.h> +#include <zmapSlave_P.h> + + + +enum {ZMAP_SLAVE_REQ_BUFSIZE = 512} ; + + + +static void cleanUpThread(void *thread_args) ; + + + + + +/* This is the routine that is called by the pthread_create() function, in effect + * this is an endless loop processing requests signalled to the thread via a + * condition variable. If this thread kills itself we will exit this routine + * normally, if the thread is cancelled however we may exit from any thread cancellable + * system call currently in progress or any of our cancellation points so its + * important that the clean up routine registered with pthread_cleanup_push() + * really does clean up properly. */ +void *zmapNewThread(void *thread_args) +{ + zmapThreadCB thread_cb ; + ZMapConnection connection = (ZMapConnection)thread_args ; + ZMapRequest thread_state = &(connection->request) ; + int status ; + TIMESPEC timeout ; + ZMapThreadRequest signalled_state ; + + + thread_cb = g_new(zmapThreadCBstruct, sizeof(zmapThreadCBstruct)) ; + thread_cb->connection = connection ; + thread_cb->thread_died = FALSE ; + thread_cb->initial_error = NULL ; + thread_cb->server = NULL ; + thread_cb->server_request = g_string_sized_new(ZMAP_SLAVE_REQ_BUFSIZE) ; + thread_cb->server_reply = NULL ; + + + /* Only do the minimum before setting this up as this is the call that makes sure our + * cleanup routine is called. */ + pthread_cleanup_push(cleanUpThread, (void *)thread_cb) ; + + if (!zMapServerCreateConnection(&(thread_cb->server), connection->machine, connection->port, + "any", "any")) + { + thread_cb->thread_died = TRUE ; + thread_cb->initial_error = g_strdup_printf("%s - %s", ZMAPSLAVE_CONNCREATE, + zMapServerLastErrorMsg(thread_cb->server)) ; + goto clean_up ; + } + + if (!zMapServerOpenConnection(thread_cb->server)) + { + thread_cb->thread_died = TRUE ; + thread_cb->initial_error = g_strdup_printf("%s - %s", ZMAPSLAVE_CONNOPEN, + zMapServerLastErrorMsg(thread_cb->server)) ; + goto clean_up ; + } + + + while (1) + { + ZMAP_THR_DEBUG(("%x: about to do timed wait\n", connection->thread_id)) ; + + /* this will crap over performance...asking the time all the time !! */ + timeout.tv_sec = 5 ; /* n.b. interface seems to absolute time. */ + timeout.tv_nsec = 0 ; + signalled_state = zmapCondVarWaitTimed(thread_state, ZMAP_REQUEST_WAIT, &timeout, TRUE) ; + + ZMAP_THR_DEBUG(("%x: finished condvar wait, state = %s\n", connection->thread_id, + zmapVarGetRequestString(signalled_state))) ; + + if (signalled_state == ZMAP_REQUEST_TIMED_OUT) + { + continue ; + } + else if (signalled_state == ZMAP_REQUEST_GETDATA) + { + static int failure = 0 ; + char *server_command ; + + ZMAP_THR_DEBUG(("%x: getting data....\n", connection->thread_id)) ; + + g_string_sprintf(thread_cb->server_request, + "gif seqget %s ; seqfeatures", connection->sequence) ; + + if (!zMapServerRequest(thread_cb->server, thread_cb->server_request->str, + &(thread_cb->server_reply))) + { + thread_cb->thread_died = TRUE ; + + /* NOTE IMPLICIT TERMINATION OF THREAD BY JUMPING OUT OF THIS LOOP + * WHICH LEADS TO EXITTING FROM THIS ROUTINE. FOR OTHER ERRORS WE WIL + * HAVE TO HAVE A MORE FORMAL MECHANISM.... */ + break ; + } + + ZMAP_THR_DEBUG(("%x: got all data....\n", connection->thread_id)) ; + + + /* Signal that we got some data. */ + zmapVarSetValueWithData(&(connection->reply), ZMAP_REPLY_GOTDATA, + (void *)(thread_cb->server_reply)) ; + + thread_cb->server_reply = NULL ; /* Reset, we don't free this string. */ + } + } + + + /* Note that once we reach here the thread will exit, the pthread_cleanup_pop(1) ensures + * we call our cleanup routine before we exit. + * Most times we will not get here because we will be pthread_cancel'd and go straight into + * our clean_up routine. */ + clean_up: + + pthread_cleanup_pop(1) ; /* 1 => always call clean up routine */ + + + ZMAP_THR_DEBUG(("%x: thread exitting from main thread routine....\n", connection->thread_id)) ; + + + return thread_args ; +} + + +/* Gets called when: + * 1) There is an error and the thread has to exit. + * 2) The thread gets cancelled, can happen in any of the POSIX cancellable + * system calls (e.g. read, select etc.) or from anywhere we declare as a cancellation point. + * + * This means some care is needed in handling resources to be released, we may need to set flags + * to remember which resources have been allocated. + * In particular we DO NOT free the thread_cb->connection, this is done by the GUI thread + * which created it. + */ +static void cleanUpThread(void *thread_args) +{ + zmapThreadCB thread_cb = (zmapThreadCB)thread_args ; + ZMapConnection connection = thread_cb->connection ; + ZMapThreadReply reply ; + gchar *error_msg = NULL ; + + printf("in cleanup routine\n") ; + + ZMAP_THR_DEBUG(("%x: in overall thread clean up routine....\n", connection->thread_id)) ; + + if (thread_cb->thread_died) + { + reply = ZMAP_REPLY_DIED ; + if (thread_cb->initial_error) + error_msg = g_strdup(thread_cb->initial_error) ; + } + else + reply = ZMAP_REPLY_CANCELLED ; + + if (thread_cb->server) + { + if (zMapServerCloseConnection(thread_cb->server) + && zMapServerFreeConnection(thread_cb->server)) + { + thread_cb->server = NULL ; + } + else + ZMAP_THR_DEBUG(("%x: Unable to close connection to server cleanly\n", + connection->thread_id)) ; + + /* this should be an error message now as well as a debug message..... */ + } + + + if (thread_cb->server_request) + g_string_free(thread_cb->server_request, TRUE) ; + if (thread_cb->server_reply) + g_free(thread_cb->server_reply) ; + + + g_free(thread_cb) ; + + + if (!error_msg) + zmapVarSetValue(&(connection->reply), reply) ; + else + zmapVarSetValueWithError(&(connection->reply), reply, error_msg) ; + + + ZMAP_THR_DEBUG(("%x: Leaving overall thread clean up routine because %s....\n", + connection->thread_id, + zmapVarGetReplyString(reply))) ; + + return ; +} + + diff --git a/src/zmapThreads/zmapSlave.test.c b/src/zmapThreads/zmapSlave.test.c new file mode 100755 index 0000000000000000000000000000000000000000..d8026e96d72d50572c47d3fd8e5928446f04b504 --- /dev/null +++ b/src/zmapThreads/zmapSlave.test.c @@ -0,0 +1,207 @@ +/* File: zmapthrslave.c + * Author: Ed Griffiths (edgrif@sanger.ac.uk) + * Copyright (c) Sanger Institute, 2003 + *------------------------------------------------------------------- + * ZMap is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * or see the on-line version at http://www.gnu.org/copyleft/gpl.txt + *------------------------------------------------------------------- + * This file is part of the ZMap genome database package + * and was written by + * Rob Clack (Sanger Institute, UK) rnc@sanger.ac.uk, + * Ed Griffiths (Sanger Institute, UK) edgrif@sanger.ac.uk and + * Simon Kelley (Sanger Institute, UK) srk@sanger.ac.uk + * + * Description: + * Exported functions: See XXXXXXXXXXXXX.h + * HISTORY: + * Last edited: Aug 6 10:16 2003 (edgrif) + * Created: Thu Jul 24 14:37:26 2003 (edgrif) + * CVS info: $Id: zmapSlave.test.c,v 1.1 2003-11-13 15:02:13 edgrif Exp $ + *------------------------------------------------------------------- + */ + +/* With some additional calls in the zmapConn code I could get rid of the need for + * the private header here...... */ + +#include <zmapConn_P.h> + + +typedef struct +{ + ZMapConnection connection ; + gboolean thread_died ; +} zmapThreadCBstruct, *zmapThreadCB ; + + + +static void delay(void) ; /* testing only */ + +static void cleanUpThread(void *thread_args) ; + + +/* This is the routine that is called by the pthread_create() function, in effect + * this is an endless loop processing requests signalled to the thread via a + * condition variable. If this thread kills itself we will exit this routine + * normally, if the thread is cancelled however we may exit from anywhere so its + * important that the clean up thread registered with pthread_cleanup_push() + * really does clean up properly. */ +void *zmapNewThread(void *thread_args) +{ + zmapThreadCB thread_cb ; + ZMapConnection connection = (ZMapConnection)thread_args ; + ZMapRequest thread_state = &(connection->request) ; + int status ; + timespec_t timeout ; + ZMapThreadRequest signalled_state ; + + + thread_cb = g_new(zmapThreadCBstruct, sizeof(zmapThreadCBstruct)) ; + thread_cb->connection = connection ; + thread_cb->thread_died = FALSE ; + + + pthread_cleanup_push(cleanUpThread, (void *)thread_cb) ; + + + while (1) + { + ZMAP_THR_DEBUG(("%x: about to do timed wait\n", connection->thread_id)) ; + + /* this will crap over performance...asking the time all the time !! */ + timeout.tv_sec = 5 ; /* n.b. interface seems to absolute time. */ + timeout.tv_nsec = 0 ; + signalled_state = zmapCondVarWaitTimed(thread_state, ZMAP_REQUEST_WAIT, &timeout, TRUE) ; + + ZMAP_THR_DEBUG(("%x: finished condvar wait, state = %s\n", connection->thread_id, + zmapVarGetRequestString(signalled_state))) ; + + if (signalled_state == ZMAP_REQUEST_TIMED_OUT) + { + continue ; + } + else if (signalled_state == ZMAP_REQUEST_GETDATA) + { + static int failure = 0 ; + char *data = NULL ; + + + /* simulation code only...in the final app we would call the socket here... */ + ZMAP_THR_DEBUG(("%x: getting data....\n", connection->thread_id)) ; + + delay() ; + pthread_testcancel() ; /* allow cancel point.... */ + delay() ; + pthread_testcancel() ; /* allow cancel point.... */ + delay() ; + pthread_testcancel() ; /* allow cancel point.... */ + delay() ; + pthread_testcancel() ; /* allow cancel point.... */ + + ZMAP_THR_DEBUG(("%x: got all data....\n", connection->thread_id)) ; + + + /* This snippet is for testing only, just fakes the thread failing. */ + failure++ ; + if (!(failure % 5)) + { + thread_cb->thread_died = TRUE ; + + /* NOTE IMPLICIT TERMINATION OF THREAD BY JUMPING OUT OF THIS LOOP + * WHICH LEADS TO EXITTING FROM THIS ROUTINE. FOR OTHER ERRORS WE WIL + * HAVE TO HAVE A MORE FORMAL MECHANISM.... */ + break ; + } + + + data = g_strdup_printf("some really wild thread data for thread %x", connection->thread_id) ; + + /* Signal that we got some data. */ + zmapVarSetValueWithData(&(connection->reply), ZMAP_REPLY_GOTDATA, (void *)data) ; + + + } + else if (signalled_state == ZMAP_REQUEST_EXIT) + { + /* THIS DOESN'T REALLY HAPPEN AT THE MOMENT.....THINK ABOUT THIS.... + * We actually just do a thread cancel because it gives better control + * to the GUI and perhaps that's the best way..... */ + + ZMAP_THR_DEBUG(("%x: gotta exit now....\n", connection->thread_id)) ; + break ; + } + } + + + /* Note that once we reach here the thread will exit, the pthread_cleanup_pop(1) ensures + * we call our cleanup routine before we exit. + * Most times we will not get here because we will be pthread_cancel'd and go straight into + * our clean_up routine. */ + + pthread_cleanup_pop(1) ; /* 1 => always call clean up routine */ + + + ZMAP_THR_DEBUG(("%x: thread exitting from main thread routine....\n", connection->thread_id)) ; + + + return thread_args ; +} + + +/* Gets called when: + * 1) There is an error and the thread has to exit. + * 2) The thread gets cancelled, can happen in any of the POSIX cancellable + * system calls (e.g. read, select etc.) or from anywhere we declare as a cancellation point. + * + * This means some care is needed in handling resources to be released, we may need to set flags + * to remember which resources have been allocated. + */ +static void cleanUpThread(void *thread_args) +{ + zmapThreadCB thread_cb = (zmapThreadCB)thread_args ; + ZMapConnection connection = thread_cb->connection ; + ZMapThreadReply reply ; + + ZMAP_THR_DEBUG(("%x: in overall thread clean up routine....\n", connection->thread_id)) ; + + if (thread_cb->thread_died) + reply = ZMAP_REPLY_DIED ; + else + reply = ZMAP_REPLY_CANCELLED ; + + zmapVarSetValue(&(connection->reply), reply) ; + + ZMAP_THR_DEBUG(("%x: Leaving overall thread clean up routine because %s....\n", + connection->thread_id, + zmapVarGetReplyString(reply))) ; + + return ; +} + + +/* Testing only.... */ +static void delay(void) +{ + enum {ITERATIONS = INT_MAX/32} ; + int i, j ; + + for (i = 0, j = 0 ; i < ITERATIONS ; i++) + { + j++ ; + } + + return ; +} + + diff --git a/src/zmapThreads/zmapSlave_P.h b/src/zmapThreads/zmapSlave_P.h new file mode 100755 index 0000000000000000000000000000000000000000..75e76a985bba6a68b19d850b5f358d26e6d33eb3 --- /dev/null +++ b/src/zmapThreads/zmapSlave_P.h @@ -0,0 +1,60 @@ +/* File: zmapSlave_P.h + * Author: Ed Griffiths (edgrif@sanger.ac.uk) + * Copyright (c) Sanger Institute, 2003 + *------------------------------------------------------------------- + * ZMap is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * or see the on-line version at http://www.gnu.org/copyleft/gpl.txt + *------------------------------------------------------------------- + * This file is part of the ZMap genome database package + * and was written by + * Ed Griffiths (Sanger Institute, UK) edgrif@sanger.ac.uk, + * Simon Kelley (Sanger Institute, UK) srk@sanger.ac.uk and + * Rob Clack (Sanger Institute, UK) rnc@sanger.ac.uk + * + * Description: + * HISTORY: + * Last edited: Sep 5 17:31 2003 (edgrif) + * Created: Wed Aug 6 15:48:47 2003 (edgrif) + * CVS info: $Id: zmapSlave_P.h,v 1.1 2003-11-13 15:02:13 edgrif Exp $ + *------------------------------------------------------------------- + */ +#ifndef ZMAP_SLAVE_P_H +#define ZMAP_SLAVE_P_H + +typedef struct +{ + ZMapConnection connection ; + gboolean thread_died ; + gchar *initial_error ; /* Holds string description of first + serious error that caused thread + termination. */ + + ZMapServer server ; + GString *server_request ; + gchar *server_reply ; + +} zmapThreadCBstruct, *zmapThreadCB ; + + + + +/* Error messages, needs some refining. */ +#define ZMAPSLAVE_CONNCREATE "Connection creation failed" +#define ZMAPSLAVE_CONNOPEN "Connection open failed" + + + + +#endif /* !ZMAP_SLAVE_P_H */ diff --git a/src/zmapUtils/README b/src/zmapUtils/README new file mode 100755 index 0000000000000000000000000000000000000000..a122f19341890c770dca5c3ff23f62664c749fb4 --- /dev/null +++ b/src/zmapUtils/README @@ -0,0 +1,4 @@ +================================================================================ +utilities + +general utility code, GUI or otherwise. diff --git a/src/zmapUtils/makefile b/src/zmapUtils/makefile new file mode 100755 index 0000000000000000000000000000000000000000..129a95183a246423a507e2244c4c0a114b632277 --- /dev/null +++ b/src/zmapUtils/makefile @@ -0,0 +1,26 @@ +# +# Makes the manager part of the ZMap application. +# + + +# local macros +UTILS_SRC = zmapGUIutils.c +UTILS_OBJ = zmapGUIutils.o + +# the main routines will need some different treatment maybe...???? try putting +# them all together, don't know if it will work..... + +# +# These must all be set for the common includes to work. +# +CURRENT_LIB = $(ZMAP_LIB) +CURRENT_OBJ = $(UTILS_OBJ) +CURRENT_DEP = +CURRENT_SRC = $(UTILS_SRC) + +# +# point to common make include file which contains all the rules etc. +# +ROOT_DIRECTORY = .. +MAKE_DIR = $(ROOT_DIRECTORY)/zmapMake +include $(MAKE_DIR)/build.make diff --git a/src/zmapUtils/zmapGUIutils.c b/src/zmapUtils/zmapGUIutils.c new file mode 100755 index 0000000000000000000000000000000000000000..9d1112d68087830487395c453da78810ff1e8042 --- /dev/null +++ b/src/zmapUtils/zmapGUIutils.c @@ -0,0 +1,110 @@ +/* File: zmapGUIutils.c + * Author: Ed Griffiths (edgrif@sanger.ac.uk) + * Copyright (c) Sanger Institute, 2003 + *------------------------------------------------------------------- + * ZMap is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * or see the on-line version at http://www.gnu.org/copyleft/gpl.txt + *------------------------------------------------------------------- + * This file is part of the ZMap genome database package + * and was written by + * Rob Clack (Sanger Institute, UK) rnc@sanger.ac.uk, + * Ed Griffiths (Sanger Institute, UK) edgrif@sanger.ac.uk and + * Simon Kelley (Sanger Institute, UK) srk@sanger.ac.uk + * + * Description: + * Exported functions: See XXXXXXXXXXXXX.h + * HISTORY: + * Last edited: Sep 9 15:15 2003 (edgrif) + * Created: Thu Jul 24 14:37:35 2003 (edgrif) + * CVS info: $Id: zmapGUIutils.c,v 1.1 2003-11-13 15:03:08 edgrif Exp $ + *------------------------------------------------------------------- + */ + +#include <gtk/gtk.h> + + +typedef struct +{ + GtkWidget *dialog ; + GtkWidget *button ; +} zmapDialogCBStruct, *zmapDialogCB ; + + + + +static void clickButton(GtkWidget *widget, zmapDialogCB cb_data) ; + + +void zmapGUIShowMsg(char *msg) +{ + GtkWidget *dialog, *label, *button; + zmapDialogCBStruct cb_data ; + + + dialog = gtk_dialog_new(); + + +#ifdef ED_G_NEVER_INCLUDE_THIS_CODE + gtk_window_set_policy( GTK_WINDOW( dialog ), FALSE, FALSE, FALSE ); +#endif /* ED_G_NEVER_INCLUDE_THIS_CODE */ + + + gtk_window_set_title( GTK_WINDOW( dialog ), "ZMAP - Error !" ); + + gtk_container_set_border_width( GTK_CONTAINER(dialog), 5 ); + + label = gtk_label_new(msg) ; + + gtk_label_set_justify( GTK_LABEL(label), GTK_JUSTIFY_CENTER ); + gtk_label_set_line_wrap( GTK_LABEL(label), TRUE ); + + gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), label, TRUE, TRUE, 20); + + button = gtk_button_new_with_label ("OK"); + GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area), + button, FALSE, FALSE, 0); + gtk_widget_grab_default (button); + gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(clickButton), &cb_data) ; + + cb_data.dialog = dialog ; + cb_data.button = button ; + + gtk_widget_show_all( dialog ); + + /* This is supposed to block interaction with the rest of the application...it doesn't. */ + gtk_grab_add(button) ; + + + /* note this call will block until user clicks....not good we need to choose when to be modal + * or not.... */ + gtk_main(); + + + return ; +} + + +static void clickButton(GtkWidget *widget, zmapDialogCB cb_data) +{ + + gtk_grab_remove(cb_data->button) ; + + gtk_widget_destroy(cb_data->dialog) ; + + gtk_main_quit() ; + + return ; +} diff --git a/src/zmapWindow/README b/src/zmapWindow/README new file mode 100755 index 0000000000000000000000000000000000000000..c44fe4c3dde143fae558c9d7113137761e65aa3b --- /dev/null +++ b/src/zmapWindow/README @@ -0,0 +1,4 @@ +================================================================================ +The ZMap window + +The code that creates a ZMap window and associated gubbins (threads etc.). diff --git a/src/zmapWindow/zmapWindow.c b/src/zmapWindow/zmapWindow.c new file mode 100755 index 0000000000000000000000000000000000000000..63287789f9284bae2f0c49cd7340465ac1b20a51 --- /dev/null +++ b/src/zmapWindow/zmapWindow.c @@ -0,0 +1,210 @@ +/* File: zmapWindow.c + * Author: Ed Griffiths (edgrif@sanger.ac.uk) + * Copyright (c) Sanger Institute, 2003 + *------------------------------------------------------------------- + * ZMap is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * or see the on-line version at http://www.gnu.org/copyleft/gpl.txt + *------------------------------------------------------------------- + * This file is part of the ZMap genome database package + * and was written by + * Rob Clack (Sanger Institute, UK) rnc@sanger.ac.uk, + * Ed Griffiths (Sanger Institute, UK) edgrif@sanger.ac.uk and + * Simon Kelley (Sanger Institute, UK) srk@sanger.ac.uk + * + * Description: + * Exported functions: See XXXXXXXXXXXXX.h + * HISTORY: + * Last edited: Aug 7 14:48 2003 (edgrif) + * Created: Thu Jul 24 14:36:27 2003 (edgrif) + * CVS info: $Id: zmapWindow.c,v 1.1 2003-11-13 15:06:17 edgrif Exp $ + *------------------------------------------------------------------- + */ + +#include <string.h> +#include <zmapWindow_P.h> + + +static void quitCB(GtkWidget *widget, gpointer cb_data) ; +static void dataEventCB(GtkWidget *widget, GdkEventClient *event, gpointer data) ; + + + +ZMapWindow zMapWindowCreate(char *machine, int port, char *sequence, + zmapVoidIntCallbackFunc manager_routine, void *manager_data) +{ + ZMapWindow window ; + GtkWidget *toplevel, *vbox, *menubar, *button_frame, *connect_frame ; + char *title ; + + window = g_new(ZMapWindowStruct, sizeof(ZMapWindowStruct)) ; + + window->machine = g_strdup(machine) ; + window->port = port ; + window->sequence = g_strdup(sequence) ; + window->manager_routine = manager_routine ; + window->manager_data = manager_data ; + window->zmap_atom = gdk_atom_intern(ZMAP_ATOM, FALSE) ; + + title = g_strdup_printf("ZMap (%s, port %d): %s", machine, port, + sequence ? sequence : "") ; + + window->toplevel = toplevel = gtk_window_new(GTK_WINDOW_TOPLEVEL) ; + gtk_window_set_policy(GTK_WINDOW(toplevel), FALSE, TRUE, FALSE ) ; + gtk_window_set_title(GTK_WINDOW(toplevel), title) ; + gtk_container_border_width(GTK_CONTAINER(toplevel), 5) ; + gtk_signal_connect(GTK_OBJECT(toplevel), "destroy", + GTK_SIGNAL_FUNC(quitCB), (gpointer)window) ; + gtk_signal_connect(GTK_OBJECT(toplevel), "client_event", + GTK_SIGNAL_FUNC(dataEventCB), (gpointer)window) ; + + vbox = gtk_vbox_new(FALSE, 0) ; + gtk_container_add(GTK_CONTAINER(toplevel), vbox) ; + + menubar = zmapWindowMakeMenuBar(window) ; + gtk_box_pack_start(GTK_BOX(vbox), menubar, FALSE, TRUE, 0); + + button_frame = zmapWindowMakeButtons(window) ; + gtk_box_pack_start(GTK_BOX(vbox), button_frame, FALSE, TRUE, 0); + + connect_frame = zmapWindowMakeFrame(window) ; + gtk_box_pack_start(GTK_BOX(vbox), connect_frame, TRUE, TRUE, 0); + + gtk_widget_show_all(toplevel) ; + + + g_free(title) ; + + + return(window) ; +} + + + +/* This routine is called by the code that manages the slave threads, it makes + * the call to tell the GUI code that there is something to do. This routine + * then sends this event to alert the GUI that it needs to do some work and + * will supply the data via the event struct. */ +void zMapWindowSignalData(ZMapWindow window, void *data) +{ + GdkEventClient event ; + GdkAtom zmap_atom ; + gint ret_val = 0 ; + zmapWindowData window_data ; + + /* Set up struct to be passed to our callback. */ + window_data = g_new(zmapWindowDataStruct, sizeof(zmapWindowDataStruct)) ; + window_data->window = window ; + window_data->data = data ; + + event.type = GDK_CLIENT_EVENT ; + event.window = NULL ; /* no window generates this event. */ + event.send_event = TRUE ; /* we sent this event. */ + event.message_type = window->zmap_atom ; /* This is our id for events. */ + event.data_format = 8 ; /* Not sure about data format here... */ + + /* Load the pointer value, not what the pointer points to.... */ + { + void **dummy ; + + dummy = (void *)&window_data ; + memmove(&(event.data.b[0]), dummy, sizeof(void *)) ; + } + + gtk_signal_emit_by_name(GTK_OBJECT(window->toplevel), "client_event", + &event, &ret_val) ; + + return ; +} + + + +void zMapWindowDestroy(ZMapWindow window) +{ + ZMAP_DEBUG(("GUI: in window destroy...\n")) ; + + /* We must disconnect the "destroy" callback otherwise we will enter quitCB() + * below and that will try to call our callers destroy routine which has already + * called this routine...i.e. a circularity which results in attempts to + * destroy already destroyed windows etc. */ + gtk_signal_disconnect_by_data(GTK_OBJECT(window->toplevel), (gpointer)window) ; + + gtk_widget_destroy(window->toplevel) ; + + g_free(window->machine) ; + g_free(window->sequence) ; + + g_free(window) ; + + return ; +} + + + +/* + * ------------------- Internal functions ------------------- + */ + + +static void quitCB(GtkWidget *widget, gpointer cb_data) +{ + ZMapWindow window = (ZMapWindow)cb_data ; + + (*(window->manager_routine))(window->manager_data, ZMAP_WINDOW_QUIT) ; + + return ; +} + + + +/* Called when gtk detects the event sent by signalDataToGUI(), in the end this + * routine will call zmap routines to display data etc. */ +static void dataEventCB(GtkWidget *widget, GdkEventClient *event, gpointer cb_data) +{ + ZMapWindow window = (ZMapWindow)cb_data ; + + if (event->type != GDK_CLIENT_EVENT) + ZMAPERR("dataEventCB() received non-GdkEventClient event") ; + + if (event->send_event == TRUE && event->message_type == gdk_atom_intern(ZMAP_ATOM, TRUE)) + { + zmapWindowData window_data = NULL ; + ZMapWindow window = NULL ; + char *string = NULL ; + + /* Retrieve the data pointer from the event struct */ + memmove(&window_data, &(event->data.b[0]), sizeof(void *)) ; + + window = window_data->window ; + string = (char *)(window_data->data) ; + + +#ifdef ED_G_NEVER_INCLUDE_THIS_CODE + ZMAP_DEBUG(("GUI: got dataEvent, contents: \"%s\"\n", string)) ; +#endif /* ED_G_NEVER_INCLUDE_THIS_CODE */ + + + gtk_text_insert(GTK_TEXT(window->text), NULL, NULL, NULL, string, strlen(string)) ; + + g_free(string) ; + g_free(window_data) ; + } + else + { + ZMAP_DEBUG(("unknown client event in zmapevent handler\n")) ; + } + + + return ; +} diff --git a/src/zmapWindow/zmapWindow_P.h b/src/zmapWindow/zmapWindow_P.h new file mode 100755 index 0000000000000000000000000000000000000000..313661d76c33463725c026b29bc6f0f1253bdeee --- /dev/null +++ b/src/zmapWindow/zmapWindow_P.h @@ -0,0 +1,77 @@ +/* File: zmapWindow_P.h + * Author: Ed Griffiths (edgrif@sanger.ac.uk) + * Copyright (c) Sanger Institute, 2003 + *------------------------------------------------------------------- + * ZMap is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * or see the on-line version at http://www.gnu.org/copyleft/gpl.txt + *------------------------------------------------------------------- + * This file is part of the ZMap genome database package + * and was written by + * Rob Clack (Sanger Institute, UK) rnc@sanger.ac.uk, + * Ed Griffiths (Sanger Institute, UK) edgrif@sanger.ac.uk and + * Simon Kelley (Sanger Institute, UK) srk@sanger.ac.uk + * + * Description: + * Exported functions: See XXXXXXXXXXXXX.h + * HISTORY: + * Last edited: Nov 13 10:26 2003 (edgrif) + * Created: Fri Aug 1 16:45:58 2003 (edgrif) + * CVS info: $Id: zmapWindow_P.h,v 1.1 2003-11-13 15:06:17 edgrif Exp $ + *------------------------------------------------------------------- + */ +#ifndef ZMAP_WINDOW_P_H +#define ZMAP_WINDOW_P_H + +#include <gtk/gtk.h> +#include <ZMap/zmapWindow.h> + +typedef struct _ZMapWindowStruct +{ + gchar *machine ; + int port ; + gchar *sequence ; + + GtkWidget *toplevel ; + GtkWidget *text ; + + GdkAtom zmap_atom ; + + zmapVoidIntCallbackFunc manager_routine ; + void *manager_data ; + +} ZMapWindowStruct ; + + +typedef struct +{ + ZMapWindow window ; + void *data ; /* void for now, union later ?? */ +} zmapWindowDataStruct, *zmapWindowData ; + + + + + +/* Used in our event communication.... */ +#define ZMAP_ATOM "ZMap_Atom" + + +GtkWidget *zmapWindowMakeMenuBar(ZMapWindow window) ; +GtkWidget *zmapWindowMakeButtons(ZMapWindow window) ; +GtkWidget *zmapWindowMakeFrame(ZMapWindow window) ; + + + +#endif /* !ZMAP_WINDOW_P_H */