@@ -794,74 +794,86 @@ class KeyManager {
794
794
// Make sure to not run in parallel
795
795
if (_uploadingFuture != null ) {
796
796
if (skipIfInProgress) return ;
797
- await _uploadingFuture;
797
+ try {
798
+ await _uploadingFuture;
799
+ } finally {
800
+ // shouldn't be necessary, since it will be unset already by the other process that started it, but just to be safe, also unset the future here
801
+ _uploadingFuture = null ;
802
+ }
798
803
}
799
- final completer = Completer <void >();
800
- _uploadingFuture = completer.future;
801
804
802
- await client.userDeviceKeysLoading;
803
- try {
804
- if (! (await isCached ())) {
805
- return ; // we can't backup anyways
806
- }
807
- final dbSessions = await database.getInboundGroupSessionsToUpload ();
808
- if (dbSessions.isEmpty) {
809
- return ; // nothing to do
810
- }
811
- final privateKey =
812
- base64decodeUnpadded ((await encryption.ssss.getCached (megolmKey))! );
813
- // decryption is needed to calculate the public key and thus see if the claimed information is in fact valid
814
- final decryption = olm.PkDecryption ();
815
- final info = await getRoomKeysBackupInfo (false );
816
- String backupPubKey;
805
+ Future <void > uploadInternal () async {
817
806
try {
818
- backupPubKey = decryption. init_with_private_key (privateKey) ;
807
+ await client.userDeviceKeysLoading ;
819
808
820
- if (info.algorithm !=
821
- BackupAlgorithm .mMegolmBackupV1Curve25519AesSha2 ||
822
- info.authData['public_key' ] != backupPubKey) {
823
- return ;
809
+ if (! (await isCached ())) {
810
+ return ; // we can't backup anyways
824
811
}
825
- final args = GenerateUploadKeysArgs (
826
- pubkey: backupPubKey,
827
- dbSessions: < DbInboundGroupSessionBundle > [],
828
- userId: userID,
829
- );
830
- // we need to calculate verified beforehand, as else we pass a closure to an isolate
831
- // with 500 keys they do, however, noticably block the UI, which is why we give brief async suspentions in here
832
- // so that the event loop can progress
833
- var i = 0 ;
834
- for (final dbSession in dbSessions) {
835
- final device =
836
- client.getUserDeviceKeysByCurve25519Key (dbSession.senderKey);
837
- args.dbSessions.add (DbInboundGroupSessionBundle (
838
- dbSession: dbSession,
839
- verified: device? .verified ?? false ,
840
- ));
841
- i++ ;
842
- if (i > 10 ) {
843
- await Future .delayed (Duration (milliseconds: 1 ));
844
- i = 0 ;
845
- }
812
+ final dbSessions = await database.getInboundGroupSessionsToUpload ();
813
+ if (dbSessions.isEmpty) {
814
+ return ; // nothing to do
846
815
}
847
- final roomKeys =
848
- await client.nativeImplementations.generateUploadKeys (args);
849
- Logs ().i ('[Key Manager] Uploading ${dbSessions .length } room keys...' );
850
- // upload the payload...
851
- await client.putRoomKeys (info.version, roomKeys);
852
- // and now finally mark all the keys as uploaded
853
- // no need to optimze this, as we only run it so seldomly and almost never with many keys at once
854
- for (final dbSession in dbSessions) {
855
- await database.markInboundGroupSessionAsUploaded (
856
- dbSession.roomId, dbSession.sessionId);
816
+ final privateKey =
817
+ base64decodeUnpadded ((await encryption.ssss.getCached (megolmKey))! );
818
+ // decryption is needed to calculate the public key and thus see if the claimed information is in fact valid
819
+ final decryption = olm.PkDecryption ();
820
+ final info = await getRoomKeysBackupInfo (false );
821
+ String backupPubKey;
822
+ try {
823
+ backupPubKey = decryption.init_with_private_key (privateKey);
824
+
825
+ if (info.algorithm !=
826
+ BackupAlgorithm .mMegolmBackupV1Curve25519AesSha2 ||
827
+ info.authData['public_key' ] != backupPubKey) {
828
+ decryption.free ();
829
+ return ;
830
+ }
831
+ final args = GenerateUploadKeysArgs (
832
+ pubkey: backupPubKey,
833
+ dbSessions: < DbInboundGroupSessionBundle > [],
834
+ userId: userID,
835
+ );
836
+ // we need to calculate verified beforehand, as else we pass a closure to an isolate
837
+ // with 500 keys they do, however, noticably block the UI, which is why we give brief async suspentions in here
838
+ // so that the event loop can progress
839
+ var i = 0 ;
840
+ for (final dbSession in dbSessions) {
841
+ final device =
842
+ client.getUserDeviceKeysByCurve25519Key (dbSession.senderKey);
843
+ args.dbSessions.add (DbInboundGroupSessionBundle (
844
+ dbSession: dbSession,
845
+ verified: device? .verified ?? false ,
846
+ ));
847
+ i++ ;
848
+ if (i > 10 ) {
849
+ await Future .delayed (Duration (milliseconds: 1 ));
850
+ i = 0 ;
851
+ }
852
+ }
853
+ final roomKeys =
854
+ await client.nativeImplementations.generateUploadKeys (args);
855
+ Logs ().i ('[Key Manager] Uploading ${dbSessions .length } room keys...' );
856
+ // upload the payload...
857
+ await client.putRoomKeys (info.version, roomKeys);
858
+ // and now finally mark all the keys as uploaded
859
+ // no need to optimze this, as we only run it so seldomly and almost never with many keys at once
860
+ for (final dbSession in dbSessions) {
861
+ await database.markInboundGroupSessionAsUploaded (
862
+ dbSession.roomId, dbSession.sessionId);
863
+ }
864
+ } finally {
865
+ decryption.free ();
857
866
}
858
- } finally {
859
- decryption. free ( );
867
+ } catch (e, s) {
868
+ Logs (). e ( '[Key Manager] Error uploading room keys' , e, s );
860
869
}
861
- } catch (e, s) {
862
- Logs ().e ('[Key Manager] Error uploading room keys' , e, s);
870
+ }
871
+
872
+ _uploadingFuture = uploadInternal ();
873
+ try {
874
+ await _uploadingFuture;
863
875
} finally {
864
- completer. complete () ;
876
+ _uploadingFuture = null ;
865
877
}
866
878
}
867
879
@@ -1185,12 +1197,12 @@ RoomKeys generateUploadKeysImplementation(GenerateUploadKeysArgs args) {
1185
1197
},
1186
1198
);
1187
1199
}
1200
+ enc.free ();
1188
1201
return roomKeys;
1189
1202
} catch (e, s) {
1190
1203
Logs ().e ('[Key Manager] Error generating payload' , e, s);
1191
- rethrow ;
1192
- } finally {
1193
1204
enc.free ();
1205
+ rethrow ;
1194
1206
}
1195
1207
}
1196
1208
0 commit comments