1010#include <sys/ipc.h>
1111#include <sys/msg.h>
1212#include <sys/stat.h>
13+ #include <unistd.h>
1314#include <pthread.h>
1415#define MAX_TYPES_NUMBER 100
1516#define MAX_RESOURCES_NUMBER 9999
@@ -59,11 +60,64 @@ pthread_mutex_t mutex;
5960 */
6061pthread_attr_t attr ;
6162
63+
64+ /*
65+ * Zmienna warunkowa do kończenia wątków.
66+ */
67+ pthread_cond_t fin_cond ;
68+
69+ /*
70+ * Zmienne warunkowe dla każdego typu.
71+ */
72+ pthread_cond_t type_cond [MAX_TYPES_NUMBER ];
73+
74+ /*
75+ * Dla każdego typu trzyma informację o czekającym żądaniu.
76+ */
77+ int type_pid [MAX_TYPES_NUMBER ];
78+ int type_N [MAX_TYPES_NUMBER ];
79+
80+ /*
81+ * Licznik dodatkowych wątków.
82+ */
83+ int thread_counter ;
84+
6285/*
63- * Metoda wątkowa .
86+ * Flaga mówiąca, czy nastąpiło przerwanie przez SIGINT .
6487 */
65- void * do_thread ()
88+ int isStopped ;
89+
90+ /*
91+ * Metoda wątku.
92+ */
93+ void * do_thread (void * data )
6694{
95+ printf ("WĄTECZEK!\n" );
96+ int th_k , n_1 , n_2 ;
97+ long pid_1 , pid_2 ;
98+
99+ sscanf ((char * ) data , "%d %li %d %li %d" , & th_k , & pid_1 , & n_1 , & pid_2 , & n_2 );
100+ printf ("AA %d %li %d %li %d\n" , th_k , pid_1 , n_1 , pid_2 , n_2 );
101+
102+ pthread_mutex_lock (& mutex );
103+ thread_counter ++ ;
104+
105+ while (resources [th_k ] < n_1 + n_2 )
106+ pthread_cond_wait (type_cond + k , & mutex );
107+
108+ thread_counter -- ;
109+ pthread_mutex_unlock (& mutex );
110+ pthread_cond_signal (& fin_cond );
111+ return 0 ;
112+ }
113+
114+ /*
115+ * Ustawia flagę mówiącą o otrzymaniu SIGINT.
116+ */
117+ void setFlag ()
118+ {
119+ printf ("Ustawiam isStopped\n" );
120+ isStopped = 1 ;
67121}
68122
69123/*
@@ -72,6 +126,9 @@ void *do_thread()
72126void free_sysres ()
73127{
74128 printf ("\nZWALNIAM ZASOBY!\n" );
129+ if (pthread_mutex_lock (& mutex ) != 0 )
130+ syserr ("Error in mutex lock sysres\n" );
131+
75132 if (msgctl (req_qid , IPC_RMID , 0 ) == -1 )
76133 syserr ("Error in msgctl\n" );
77134
@@ -81,9 +138,41 @@ void free_sysres()
81138 if (msgctl (fin_qid , IPC_RMID , 0 ) == -1 )
82139 syserr ("Error in msgctl\n" );
83140
141+ if (pthread_cond_destroy (& fin_cond ) != 0 )
142+ syserr ("Error in destroy fin_cond\n" );
143+
144+ for (int i = 1 ; i <= K ; i ++ )
145+ if (pthread_cond_destroy (type_cond + i ) != 0 )
146+ syserr ("Error in destroy type_cond %d" , i );
147+
148+ //if (pthread_mutex_destroy(&mutex) != 0)
149+ // syserr("Error in mutex destroy\n");
150+
84151 exit (0 );
85152}
86153
154+ /*
155+ * Tworzy obiekty do obsługi wątków.
156+ */
157+ void create_thread_tools ()
158+ {
159+ if ((pthread_mutex_init (& mutex , 0 )) != 0 )
160+ syserr ("mutex init\n" );
161+
162+ if ((pthread_attr_init (& attr )) != 0 )
163+ syserr ("attr init\n" );
164+
165+ if ((pthread_attr_setdetachstate (& attr , PTHREAD_CREATE_DETACHED )) != 0 )
166+ syserr ("setdetach\n" );
167+
168+ if ((pthread_cond_init (& fin_cond , 0 )) != 0 )
169+ syserr ("init fin_cond\n" );
170+
171+ for (int i = 1 ; i <= K ; i ++ )
172+ if ((pthread_cond_init (type_cond + i , 0 )) != 0 )
173+ syserr ("init type_cond %d\n" , i );
174+ }
175+
87176/*
88177 * Metoda tworząca kolejki komunkatów.
89178 */
@@ -115,33 +204,50 @@ int main(int argc, char* argv[])
115204
116205 K = atoi (argv [1 ]);
117206 N = atoi (argv [2 ]);
207+ isStopped = 0 ;
118208
119209 for (int i = 1 ; i <= K ; i ++ )
120210 resources [i ] = N ;
121211
122- if ( signal (SIGINT , free_sysres ) == SIG_ERR )
123- syserr ("Error in signal\n" );
124-
125- if ((pthread_mutex_init (& mutex , 0 )) != 0 )
126- syserr ("mutex init\n" );
127-
128- if ((pthread_attr_init (& attr )) != 0 )
129- syserr ("attr init\n" );
212+ create_thread_tools ();
130213
131- if (( pthread_attr_setdetachstate ( & attr , PTHREAD_CREATE_DETACHED )) != 0 )
132- syserr ("setdetach \n" );
214+ if ( signal ( SIGINT , free_sysres ) == SIG_ERR )
215+ syserr ("Error in signal \n" );
133216
134217 create_queues ();
135218
136219 int size_rcv ;
137- while ((size_rcv = msgrcv (req_qid , & msg , MAX_DATA_SIZE , 0 , 0 )))
220+ char msg_buf [100 ];
221+ while ((size_rcv = msgrcv (req_qid , & msg , MAX_DATA_SIZE , 0 , 0 )) && isStopped == 0 )
138222 {
139223 printf ("DOSTALEM REQUEST! :) %s\n" , msg .data );
140- if ( signal (SIGINT , free_sysres ) == SIG_ERR )
224+ if ( signal (SIGINT , setFlag ) == SIG_ERR )
141225 syserr ("Error in signal\n" );
142226
227+ int th_id , k_req , n_req ;
228+ sscanf (msg .data , "%d %d" , & k_req , & n_req );
229+
230+ //pthread_mutex_lock(&mutex);
231+ if (type_pid [k_req ] == 0 )
232+ {
233+ type_pid [k_req ] = msg .msg_type ;
234+ type_N [k_req ] = n_req ;
235+ }
236+ else
237+ {
238+ pthread_t th ;
239+ sprintf (msg_buf , "%d %li %d %d %d" , k_req , msg .msg_type , n_req ,
240+ type_pid [k_req ], type_N [k_req ]);
241+ type_pid [k_req ] = 0 ;
242+ type_N [k_req ] = 0 ;
243+ th_id = pthread_create (& th , & attr , do_thread , msg_buf );
244+ }
245+ //pthread_mutex_unlock(&mutex);
143246 }
144247
248+ while (thread_counter > 0 )
249+ pthread_cond_wait (& fin_cond , & mutex );
250+
145251 free_sysres ();
146252 exit (0 );
147253}
0 commit comments