+pthread_mutex_t gateMutex;
+pthread_cond_t gateBroadCast;
+bool isGateOpen = false;
+int threadsNumber = 20;
+
+
struct sigaction sigintAction; /*Stores the init SIGINT sigaction value*/
-char *fileName;
+char *fileName = "/tmp/locks";
int c; /*Getopt parameter*/
/*Default values*/
struct sigaction sa; /*sig actions values*/
- bool isFileLock = false;
bool isThread = false;
- fileName = "/tmp/locks";
-
opterr = 0;
while ((c = getopt (argc, argv, "p:tf:")) != -1) {
fileName = optarg;
break;
case 't':
- isFileLock = true;
+ threadsNumber = atoi(optarg);
break;
case 'f':
isThread = true;
int main_process ()
{
- pthread_t idThreadOne; /*Thread one identifier number*/
- pthread_t idThreadTwo; /*Thread two identifier number*/
-
+ int createIndex;
+ int joinIndex;
+ pthread_t threadIds [threadsNumber]; /*Threads identifier numbers*/
- if (pthread_create (&idThreadOne, NULL, thread_one, NULL) != 0 ) {
- fprintf (stderr, "%s: %s\n", "thread one creation failed", strerror(errno));
- fflush (stderr);
-
- return -1;
- }
+ pthread_mutex_init(&gateMutex, NULL);
+ pthread_cond_init(&gateBroadCast, NULL);
+ closeGate();
- // Let other thread progress. Should be enough with sleep. This code is just for testing.
- sleep(10);
- if (pthread_create (&idThreadTwo, NULL, thread_two, NULL) != 0 ) {
- fprintf (stderr, "%s: %s\n", "thread two creation failed", strerror(errno));
- fflush (stderr);
-
- return -1;
- }
+ for (createIndex = 0; createIndex < threadsNumber; createIndex++) {
+ print_with_date (stdout, "Thread %d created\n", createIndex);
+ if (pthread_create (&threadIds[createIndex], NULL, &thread_lock, (void *) createIndex) != 0 ) {
+ print_with_date (stderr, "Thread %d creation failed\n", createIndex, strerror(errno));
+ break;
+ }
+ }
- sleep(90);
+ sleep(5);
+ openGate();
+ for (joinIndex = createIndex; joinIndex --> 0; ) {
+ if (pthread_join(threadIds[joinIndex], NULL) != 0) {
+ print_with_date (stderr, "Thread %d join error\n", joinIndex, strerror(errno));
+ }
+ }
+
return 0;
}
-void *thread_one(void * arg) {
+void *thread_lock(void * arg) {
+ int threadNumber;
int fd;
int flockErr;
- fd = open(fileName, O_CREAT | O_RDWR, 0664);
- if (fd == -1) {
- print_with_date (stderr, "%s\n", "ThreadOne, open file error", strerror(errno));
- }
-
- print_with_date (stdout, "ThreadOne: before lock\n");
- do {
- flockErr = flock(fd, LOCK_EX);
- } while(flockErr == -1 && errno == EINTR);
-
-
- if (flockErr == -1) {
- print_with_date (stderr, "%s: %s\n", "threadOne, flock error", strerror(errno));
- }
- print_with_date (stdout, "ThreadOne: after lock\n");
-
- sleep(30);
+ threadNumber = (int) arg;
- print_with_date (stdout, "ThreadOne: before release lock\n");
- do {
- flockErr = flock(fd, LOCK_UN);
- } while(flockErr == -1 && errno == EINTR);
- print_with_date (stdout, "ThreadOne: after release lock\n");
-
- close (fd);
-
- pthread_exit(0);
-}
-
-void *thread_two(void * arg) {
- int fd;
- int flockErr;
+ gate();
fd = open(fileName, O_CREAT | O_RDWR, 0664);
if (fd == -1) {
- print_with_date (stderr, "%s: %s\n", "ThreadTwo, open file error", strerror(errno));
+ print_with_date (stderr, "Thread %d, open file error", threadNumber, strerror(errno));
}
-
- print_with_date (stdout, "ThreadTwo: before lock\n");
+
+ print_with_date (stdout, "Thread %d: before lock\n", threadNumber);
do {
flockErr = flock(fd, LOCK_EX);
} while(flockErr == -1 && errno == EINTR);
if (flockErr == -1) {
- print_with_date (stderr, "%s: %s\n", "ThreadTwo, flock error", strerror(errno));
+ print_with_date (stderr, "Thread %d: flock error", threadNumber, strerror(errno));
}
- print_with_date (stdout, "ThreadTwo: after lock\n");
+ print_with_date (stdout, "Thread %d: after lock\n", threadNumber);
+ sleep(5);
- print_with_date (stdout, "ThreadTwo: before release lock\n");
+ print_with_date (stdout, "Thread %d: before release lock\n", threadNumber);
do {
flockErr = flock(fd, LOCK_UN);
} while(flockErr == -1 && errno == EINTR);
- print_with_date (stdout, "ThreadTwo: after release lock\n");
+ print_with_date (stdout, "Thread %d: after release lock\n", threadNumber);
close (fd);
}
}
+void gate() {
+
+ pthread_mutex_lock(&gateMutex);
+
+ while(!isGateOpen) {
+ pthread_cond_wait(&gateBroadCast, &gateMutex);
+ }
+
+ pthread_mutex_unlock(&gateMutex);
+}
+
+void openGate() {
+ pthread_mutex_lock(&gateMutex);
+
+ isGateOpen = true;
+ pthread_cond_broadcast(&gateBroadCast);
+
+ pthread_mutex_unlock(&gateMutex);
+}
+
+void closeGate() {
+ pthread_mutex_lock(&gateMutex);
+
+ isGateOpen = false;
+
+ pthread_mutex_unlock(&gateMutex);
+}
+
void sigint_handler(int sig)
{
/*TODO: kill child processes, finish threads and release allocate memory*/