#ifndef extc_phase2_h_ #define extc_phase2_h_ /*************************************************************************** * phase2.h * * Tue Jul 26 13:42:18 2005 * Copyright 2005 James Scully- aka jtox * Email jtoxification @ the-only-free-2-gig-account-service-online *************************************************************************** * This program 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 Library 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 */ /* Extended C Phase #2: The *this pointer. */ /* Jamie Scully - July 21st, 2005 */ /* in Phase #2, we are using somewhat of a layered approach, where we use object-orientedness since we know there will be only one object registry in a given program -- we just create a global *self pointer with static scope for our functions. For thoes of you who have need for only single objects such as this one, you may want to copy this design. And for those of you who /know/ what you are doing, There will be a mixed version of this design and the design specified in phase 1, to cut down on redundancy. Furthermore, once again, yes, I do know about C++'s extern C {#include <INSERT NAME OF C HEADER>} */ #include "phase5.h" #include "hash.h" extern int MUTEX__ (int*); extern int SemP__ (int*); extern int SemV__ (int*); static int find___ (); static void*current___ (int pid,int tid); static void* pop___ (int pid,int tid); static void remove___ (void* item ); //static void exists___ (void* item ); static int lock___ (); static void unlock___ (); static void add___ (); static int slock___ (); static void unslock___ (); static unsigned long long i2ull___(int pid,int tid); /* The object registry ! */ typedef struct Registry { int (* lock) (); void (* unlock) (); int (* slock) (); void (* unslock) (); int (* find) (); void*(* current) (); void (* add) (); void*(* pop) (); void (* remove) (); // void (* exists) (); } Registry; //Private /////////////////////////////...///////////////////////////////////// /* I made this version of the registry in a bit of a hurry. That's why its not a fully-optimized hash-array. I'll swap it out later, but for now, it works, and well! BEFORE YOU ASK: Yes, the hash code sucks. Yes there is an interface to this if you want to make your own backend rather than the hash table. Yes I know about C++'s extern C {#include <name of c header>} */ static int registry_mutex; static int this_mutex; static Registry registry__[1] = { (Registry) { lock___, unlock___, slock___, unslock___, find___, current___, add___, pop___, remove___ } }; //Functions /////////////////////////////...////////////////////////////////// static int lock___() {SemP__(®istry_mutex);return 0;} static void unlock___() {SemV__(®istry_mutex); } static int slock___() {SemP__(&this_mutex );return 0;} static void unslock___() {SemV__(&this_mutex ); } static int find___() { void* v = obj_db->search(); unlock___(); unsigned long long ull = i2ull___(GETPID(),GETTID()); slock___(); self_db->add(v,ull); unslock___(); return 0; } static unsigned long long i2ull___(int pid,int tid) { union llii___{ int i[2];unsigned long long ll; } il[1]; il->i[0]=pid; il->i[1]=tid; return il->ll; } /*warning: wrap calls to this around registry__->slock()/->unslock();*/ static void* current___(int pid,int tid) { return self_db->search(i2ull___(pid,tid)); } static void* pop___(int pid,int tid) { slock___(); return self_db->remove(i2ull___(pid,tid)); unslock___(); } static void remove___(void* item) { lock___(); obj_db->remove(item); unlock___(); } static void add___(void* item) { static int started; /* This style below serves no real purpose, except to remind you that you'll soon need a way to prevent this code from occurring multiple times (race condition) Change it later. The array-of-multiple-functionpointers whose functions modify the array index wouldn't work because it's actually more work to call the function and dereference the pointer and array than to simply use an if-statement: only use self-modifying functionpointer arrays when you're calling other functions, NOT when you're using conditional expressions. */ if (!started && ++started) { MUTEX__(&this_mutex ); MUTEX__(®istry_mutex); initialize_database(); } lock___(); obj_db->add(item); unlock___(); } #endif