Skip to content

Commit 8e2c943

Browse files
author
vnavarro
committed
Writing the code
1 parent f3d8012 commit 8e2c943

File tree

6 files changed

+245
-0
lines changed

6 files changed

+245
-0
lines changed

Makefile.am

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
SUBDIRS = src

README.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ First install the necessary system tools. If you use Debian-like distributions:
3030

3131
sudo apt-get install build-essential
3232
sudo apt-get install automake autoconf libtool
33+
sudo apt-get install libsqlite3-dev liblog4cpp5-dev
34+
35+
Please, __Note__ that we install libsqlite3-dev and liblog4cpp5-dev but only to start development more quickly.
3336

3437
Now, we need to edit 4 files to handle all the project needs. Run these commands to create the source tree:
3538

@@ -52,3 +55,22 @@ to get this _project tree_:
5255

5356
[commit]()
5457
[tree]()
58+
59+
## Writing the code
60+
61+
__autogen.sh__ creates some standard needed files and it runs autoreconf to create all config files needed to build the project.
62+
63+
__configure.ac__ contains invocations of the Autoconf macros that test the system features the package needs.
64+
65+
Please, __Note__ that we check for sqlite3 and log4cpp system libraries. Let's make the application code run and we will worry about them later.
66+
67+
__Makefile.am__ contains a simple definition of the subdirectories containing source code.
68+
69+
__src/Makefile.am__ defines the _SOURCES_ needed to build our _PROGRAMS_
70+
71+
__src/main.cpp__ is the application source code.
72+
73+
[commit]()
74+
[tree]()
75+
76+

autogen.sh

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#! /bin/sh
2+
3+
echo "running autoreconf ... "
4+
ln -s README.md README
5+
touch NEWS ChangeLog AUTHORS
6+
7+
autoreconf --force --install --verbose
8+
9+
if test "$?" -eq "0"
10+
then
11+
echo "package ready to run ./configure && make && make install"
12+
else
13+
echo "autoreconf failed!"
14+
exit 1
15+
fi

configure.ac

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Init autoconf
2+
AC_INIT([nesting], [0.1.0], [[email protected]])
3+
# Init automake
4+
AM_INIT_AUTOMAKE([-Wall -Werror])
5+
# Configure C++ compiler
6+
AC_PROG_CXX
7+
# Auto config headers
8+
AC_CONFIG_HEADERS([config.h])
9+
10+
# Check for neede system libraries
11+
AC_CHECK_LIB(sqlite3, main,,AC_MSG_ERROR(nesting requires sqlite3))
12+
AC_CHECK_LIB(log4cpp, main,,AC_MSG_ERROR(nesting requires liblog4cpp))
13+
14+
# Output files
15+
AC_CONFIG_FILES([Makefile src/Makefile])
16+
AC_OUTPUT
17+

src/Makefile.am

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
bin_PROGRAMS = nesting
2+
nesting_SOURCES = main.cpp

src/main.cpp

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
/*
2+
nesting! with autotools and some threading
3+
Copyright (C) 2013 Víctor Navarro
4+
5+
This program is free software: you can redistribute it and/or modify
6+
it under the terms of the GNU General Public License as published by
7+
the Free Software Foundation, either version 3 of the License, or
8+
(at your option) any later version.
9+
10+
This program is distributed in the hope that it will be useful,
11+
but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
GNU General Public License for more details.
14+
15+
You should have received a copy of the GNU General Public License
16+
along with this program. If not, see <http://www.gnu.org/licenses/>.
17+
*/
18+
#include <stdlib.h>
19+
#include <string>
20+
#include <sstream>
21+
#include <list>
22+
#include <iostream>
23+
24+
#include <pthread.h>
25+
#include <signal.h>
26+
#include <sys/select.h>
27+
extern "C" {
28+
#include <sqlite3.h>
29+
}
30+
31+
#include <log4cpp/Category.hh>
32+
#include <log4cpp/Appender.hh>
33+
#include <log4cpp/FileAppender.hh>
34+
#include <log4cpp/OstreamAppender.hh>
35+
#include <log4cpp/Layout.hh>
36+
#include <log4cpp/BasicLayout.hh>
37+
#include <log4cpp/Priority.hh>
38+
39+
using namespace std;
40+
41+
#define DATABASE "database.sqlite"
42+
#define NUM_THREADS 101
43+
44+
// the lock
45+
pthread_mutex_t lock;
46+
47+
// the shared resource
48+
std::list< std::string > queue;
49+
50+
extern "C" {
51+
void *worker(void *arg);
52+
}
53+
54+
void *worker(void *arg)
55+
{
56+
sqlite3 *db;
57+
char *zErrMsg = 0;
58+
59+
pthread_mutex_lock( &lock );
60+
61+
if (queue.size() != 0) {
62+
// insert a record into the database
63+
sqlite3_open(DATABASE, &db);
64+
sqlite3_exec(db, "INSERT INTO records VALUES(NULL)", NULL, 0, &zErrMsg);
65+
sqlite3_free(zErrMsg);
66+
sqlite3_close(db);
67+
68+
queue.pop_front();
69+
}
70+
pthread_mutex_unlock( &lock );
71+
72+
//std::cout << "done.\n";
73+
pthread_exit(NULL);
74+
}
75+
76+
77+
int main (int argc, char *argv[])
78+
{
79+
unsigned int i;
80+
int rc;
81+
sqlite3 *db;
82+
sqlite3_stmt *stmt;
83+
char *zErrMsg = 0;
84+
85+
std::string sString;
86+
87+
log4cpp::Appender *appender2 = new log4cpp::FileAppender("default", "nesting.log");
88+
log4cpp::Category& root = log4cpp::Category::getRoot();
89+
90+
log4cpp::Category& sub = log4cpp::Category::getInstance(std::string("nesting"));
91+
sub.addAppender(appender2);
92+
93+
// setup the database
94+
if (sqlite3_open_v2(DATABASE, &db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL) == SQLITE_OK) {
95+
if (sqlite3_exec(db, "CREATE TABLE IF NOT EXISTS records (ID INTEGER PRIMARY KEY NOT NULL)", NULL, NULL, &zErrMsg) != SQLITE_OK) {
96+
sString = "Failed to create table\n";
97+
std::cout << sString;
98+
sub.error(sString);
99+
exit(-1);
100+
}
101+
if (sqlite3_exec(db, "DELETE FROM records", NULL, NULL, &zErrMsg) != SQLITE_OK) {
102+
sString = "Failed to delete records\n";
103+
std::cout << sString;
104+
sub.error(sString);
105+
exit(-1);
106+
}
107+
sqlite3_close(db);
108+
}
109+
else {
110+
sString = "Failed to open/create database\n";
111+
std::cout << sString;
112+
sub.error(sString);
113+
exit(-1);
114+
}
115+
116+
// set-up mutex
117+
pthread_mutex_init( &lock, NULL );
118+
119+
std::cout << "Starting " << NUM_THREADS << " threads to store " << NUM_THREADS << " records\n";
120+
sub.info("Starting %d threads to store %d records\n", NUM_THREADS, NUM_THREADS);
121+
122+
for (i = 0; i < NUM_THREADS; i++) {
123+
std::stringstream ss_id;
124+
ss_id << "id " << i;
125+
queue.push_back(ss_id.str());
126+
}
127+
128+
// setup a list for thread's id
129+
std::list< pthread_t* > thread_list;
130+
131+
// start the threads
132+
for (i = 0; i < NUM_THREADS; i++) {
133+
pthread_t *thread_id (new pthread_t);
134+
thread_list.push_back(thread_id);
135+
rc = pthread_create( thread_id , NULL, worker, NULL);
136+
if (rc) {
137+
sString = "thread_create() error\n";
138+
std::cout << sString;
139+
sub.error(sString);
140+
exit(-1);
141+
}
142+
}
143+
144+
// join threads
145+
std::list< pthread_t* >::iterator it(thread_list.begin());
146+
while (it != thread_list.end()) {
147+
if (pthread_join( *(*it), NULL) != 0) {
148+
sString = "pthread_join() error!\n";
149+
std::cout << sString;
150+
sub.error(sString);
151+
exit(1);
152+
}
153+
delete (*it);
154+
thread_list.erase(it++);
155+
}
156+
157+
// clean
158+
pthread_mutex_destroy(&lock);
159+
160+
// print records
161+
std::cout << "<xml>\n";
162+
sqlite3_open(DATABASE, &db);
163+
sqlite3_prepare_v2(db, "SELECT * FROM records", -1, &stmt, 0);
164+
do {
165+
rc = sqlite3_step(stmt);
166+
switch(rc){
167+
case SQLITE_DONE:
168+
break;
169+
case SQLITE_ROW:
170+
sString = std::string(reinterpret_cast<const char*>(sqlite3_column_text(stmt, 0)));
171+
std::cout << "\t<inicio indice=" << sString << ">HolaMundo</inicio>\n";
172+
break;
173+
default:
174+
std::cout << "sqlite3_step() error.";
175+
break;
176+
}
177+
} while (rc==SQLITE_ROW);
178+
sqlite3_finalize(stmt);
179+
sqlite3_close(db);
180+
std::cout << "</xml>\n";
181+
182+
183+
sString = "all done!\n";
184+
std::cout << sString;
185+
sub.info(sString);
186+
187+
return(0);
188+
}

0 commit comments

Comments
 (0)