diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/common.h | 143 | ||||
-rw-r--r-- | lib/config.h | 2 | ||||
-rw-r--r-- | lib/db.c | 1 | ||||
-rw-r--r-- | lib/db.h | 94 | ||||
-rw-r--r-- | lib/demo.c | 2 | ||||
-rw-r--r-- | lib/tabledef.c | 6 | ||||
-rw-r--r-- | lib/tabledef.h | 6 | ||||
-rw-r--r-- | lib/test.c | 2 |
8 files changed, 223 insertions, 33 deletions
diff --git a/lib/common.h b/lib/common.h index 5aa4819..e757e3d 100644 --- a/lib/common.h +++ b/lib/common.h @@ -11,6 +11,7 @@ #include <stdint.h> // uint_64_t #include <stdlib.h> #include <string.h> +#include <errno.h> #include <string> #include <openssl/md5.h> // MD5_* @@ -281,4 +282,146 @@ class LogDuration }; //*************************************************************************** +// Semaphore +//*************************************************************************** + +#include <sys/sem.h> + +class Sem +{ + public: + + Sem(key_t aKey) + { + locked = no; + key = aKey; + + if ((id = semget(key, 1, 0666 | IPC_CREAT)) == -1) + tell(0, "Error: Can't get semaphore, errno (%d) '%s'", + errno, strerror(errno)); + } + + ~Sem() + { + if (locked) + v(); + } + + // ---------------------- + // get lock + + int p() + { + sembuf sops[2]; + + sops[0].sem_num = 0; + sops[0].sem_op = 0; // wait for lock + sops[0].sem_flg = SEM_UNDO; + + sops[1].sem_num = 0; + sops[1].sem_op = 1; // increment + sops[1].sem_flg = SEM_UNDO | IPC_NOWAIT; + + if (semop(id, sops, 2) == -1) + { + tell(0, "Error: Can't lock semaphore, errno (%d) '%s'", + errno, strerror(errno)); + + return fail; + } + + locked = yes; + + return success; + } + + // ---------------------- + // increment + + int inc() + { + sembuf sops[1]; + + sops[0].sem_num = 0; + sops[0].sem_op = 1; // increment + sops[0].sem_flg = SEM_UNDO | IPC_NOWAIT; + + if (semop(id, sops, 1) == -1) + { + if (errno != EAGAIN) + tell(0, "Error: Can't lock semaphore, errno was (%d) '%s'", + errno, strerror(errno)); + + return fail; + } + + locked = yes; + + return success; + } + + // ---------------------- + // decrement + + int dec() + { + return v(); + } + + // ---------------------- + // check + + int check() + { + sembuf sops[1]; + + sops[0].sem_num = 0; + sops[0].sem_op = 0; + sops[0].sem_flg = SEM_UNDO | IPC_NOWAIT; + + if (semop(id, sops, 1) == -1) + { + if (errno != EAGAIN) + tell(0, "Error: Can't lock semaphore, errno was (%d) '%s'", + errno, strerror(errno)); + + return fail; + } + + return success; + } + + // ---------------------- + // release lock + + int v() + { + sembuf sops; + + sops.sem_num = 0; + sops.sem_op = -1; // release control + sops.sem_flg = SEM_UNDO | IPC_NOWAIT; + + if (semop(id, &sops, 1) == -1) + { + if (errno != EAGAIN) + tell(0, "Error: Can't unlock semaphore, errno (%d) '%s'", + errno, strerror(errno)); + + return fail; + } + + locked = no; + + return success; + } + + private: + + key_t key; + int id; + int locked; +}; + +//*************************************************************************** #endif //___COMMON_H diff --git a/lib/config.h b/lib/config.h index 4389c58..f32877a 100644 --- a/lib/config.h +++ b/lib/config.h @@ -11,6 +11,8 @@ #include "common.h" +#define EPG_PLUGIN_SEM_KEY 0x3db00001 + //*************************************************************************** // Config //*************************************************************************** @@ -512,6 +512,7 @@ int cDbConnection::dbPort = 3306; char* cDbConnection::dbUser = 0; char* cDbConnection::dbPass = 0; char* cDbConnection::dbName = 0; +Sem* cDbConnection::sem = 0; //*************************************************************************** // Object @@ -8,11 +8,15 @@ #ifndef __DB_H #define __DB_H +#include <linux/unistd.h> + +#include <unistd.h> #include <stdlib.h> #include <string.h> #include <stdio.h> #include <stdarg.h> #include <errno.h> + #include <mysql/mysql.h> #include <list> @@ -550,13 +554,11 @@ class cDbConnection virtual ~cDbConnection() { - if (mysql) - { - mysql_close(mysql); - mysql_thread_end(); - } + close(); } + int isConnected() { return getMySql() > 0; } + int attachConnection() { static int first = yes; @@ -565,14 +567,16 @@ class cDbConnection { connectDropped = yes; + tell(0, "Calling mysql_init(%ld)", syscall(__NR_gettid)); + if (!(mysql = mysql_init(0))) return errorSql(this, "attachConnection(init)"); if (!mysql_real_connect(mysql, dbHost, dbUser, dbPass, dbName, dbPort, 0, 0)) { - mysql_close(mysql); - mysql = 0; + close(); + tell(0, "Error, connecting to database at '%s' on port (%d) failed", dbHost, dbPort); @@ -601,19 +605,25 @@ class cDbConnection return success; } - void detachConnection() - { - attached--; - - if (!attached) + void close() + { + if (mysql) { + tell(0, "Closing mysql connection and calling mysql_thread_end(%ld)", syscall(__NR_gettid)); + mysql_close(mysql); mysql_thread_end(); mysql = 0; } } - int isConnected() { return getMySql() > 0; } + void detachConnection() + { + attached--; + + if (!attached) + close(); + } int check() { @@ -724,12 +734,7 @@ class cDbConnection MYSQL* getMySql() { if (connectDropped && mysql) - { - mysql_close(mysql); - mysql_thread_end(); - mysql = 0; - attached = 0; - } + close(); return mysql; } @@ -756,22 +761,59 @@ class cDbConnection int errorSql(cDbConnection* mysql, const char* prefix, MYSQL_STMT* stmt = 0, const char* stmtTxt = 0); - void showStat(const char* name = "") { statements.showStat(name); } + void showStat(const char* name = "") { statements.showStat(name); } + + // ----------------------------------------------------------- + // init() and exit() must exactly called 'once' per process - static int init() + static int init(key_t semKey) { - if (mysql_library_init(0, 0, 0)) + if (semKey && !sem) + sem = new Sem(semKey); + + if (!sem || sem->check() == success) + { + // call only once per process + + if (sem) + tell(1, "Info: Calling mysql_library_init()"); + + if (mysql_library_init(0, 0, 0)) + { + tell(0, "Error: mysql_library_init() failed"); + return fail; + } + } + else if (sem) { - tell(0, "Error: mysql_library_init failed"); - return fail; // return errorSql(0, "init(library_init)"); + tell(1, "Info: Skipping calling mysql_library_init(), it's already done!"); } + if (sem) + sem->inc(); // count usage per process + return success; } static int exit() { - mysql_library_end(); + mysql_thread_end(); + + if (sem) + sem->dec(); + + if (!sem || sem->check() == success) + { + if (sem) + tell(1, "Info: Released the last usage of mysql_lib, calling mysql_library_end() now"); + + mysql_library_end(); + } + else if (sem) + { + tell(1, "Info: The mysql_lib is still in use, skipping mysql_library_end() call"); + } + free(dbHost); free(dbUser); free(dbPass); @@ -792,6 +834,8 @@ class cDbConnection int inTact; int connectDropped; + static Sem* sem; + static char* encoding; // connecting data @@ -15,7 +15,7 @@ const char* logPrefix = "demo"; void initConnection() { - cDbConnection::init(); + cDbConnection::init(0x3db00012); cDbConnection::setEncoding("utf8"); cDbConnection::setHost("localhost"); diff --git a/lib/tabledef.c b/lib/tabledef.c index d9826f5..3ea28c1 100644 --- a/lib/tabledef.c +++ b/lib/tabledef.c @@ -117,9 +117,9 @@ cDbService::FieldDef cTableEvents::fields[] = // episodes (constable) - { "episode", ffAscii, 250, fiEpisode, ftData }, - { "episodepart", ffAscii, 250, fiEpisodePart, ftData }, - { "episodelang", ffAscii, 3, fiEpisodeLang, ftData }, +// { "episodecompname", ffAscii, 250, fiEpisode, ftData }, +// { "episodecomppartname", ffAscii, 250, fiEpisodePart, ftData }, +// { "episodelang", ffAscii, 3, fiEpisodeLang, ftData }, // tv scraper diff --git a/lib/tabledef.h b/lib/tabledef.h index 9936f4e..9e6e83d 100644 --- a/lib/tabledef.h +++ b/lib/tabledef.h @@ -251,9 +251,9 @@ class cTableEvents : public cDbTable fiExtEpNum, fiImageCount, - fiEpisode, - fiEpisodePart, - fiEpisodeLang, +// fiEpisode, +// fiEpisodePart, +// fiEpisodeLang, fiScrSeriesId, fiScrSeriesEpisode, @@ -21,7 +21,7 @@ const char* logPrefix = "test"; void initConnection() { - cDbConnection::init(); + cDbConnection::init(0x3db00011); cDbConnection::setEncoding("utf8"); cDbConnection::setHost("localhost"); |